Fixes code style and some warnings
This commit is contained in:
parent
3db0627cc7
commit
80ed7838d9
@ -34,10 +34,9 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
{
|
||||
public class ArmoredElytra extends JavaPlugin implements Listener {
|
||||
private static final MinecraftVersion minecraftVersion = MinecraftVersion
|
||||
.get(Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]);
|
||||
.get(Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]);
|
||||
|
||||
private static ArmoredElytra INSTANCE;
|
||||
private Messages messages;
|
||||
@ -49,11 +48,9 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
private NBTEditor nbtEditor;
|
||||
|
||||
@Override
|
||||
public void onEnable()
|
||||
{
|
||||
public void onEnable() {
|
||||
INSTANCE = this;
|
||||
if (minecraftVersion.isOlderThan(MinecraftVersion.v1_17))
|
||||
{
|
||||
if (minecraftVersion.isOlderThan(MinecraftVersion.v1_17)) {
|
||||
myLogger(Level.SEVERE, "Trying to run this plugin on an unsupported version... ABORT!");
|
||||
setEnabled(false);
|
||||
return;
|
||||
@ -73,185 +70,167 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
// Check if the user allows checking for updates.
|
||||
updateManager.setEnabled(config.checkForUpdates());
|
||||
|
||||
if (config.allowStats())
|
||||
{
|
||||
if (config.allowStats()) {
|
||||
myLogger(Level.INFO, "Enabling stats! Thanks, it really helps!");
|
||||
@SuppressWarnings("unused") final Metrics metrics = new Metrics(this, 1656);
|
||||
}
|
||||
else
|
||||
// Y u do dis? :(
|
||||
} else
|
||||
// Y u do dis? :(
|
||||
{
|
||||
myLogger(Level.INFO,
|
||||
"Stats disabled, not loading stats :(... Please consider enabling it! I am a simple man, " +
|
||||
"seeing higher user numbers helps me stay motivated!");
|
||||
"Stats disabled, not loading stats :(... Please consider enabling it! I am a simple man, " +
|
||||
"seeing higher user numbers helps me stay motivated!");
|
||||
}
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new EventHandlers(this, nbtEditor, durabilityManager), this);
|
||||
Objects.requireNonNull(getCommand("ArmoredElytra"), "ArmoredElytra base command not found!")
|
||||
.setExecutor(new CommandHandler(this, nbtEditor, durabilityManager));
|
||||
.setExecutor(new CommandHandler(this, nbtEditor, durabilityManager));
|
||||
|
||||
// Load the plugin normally if not in uninstall mode.
|
||||
if (!config.uninstallMode())
|
||||
{
|
||||
if (!config.uninstallMode()) {
|
||||
Bukkit.getPluginManager().registerEvents(new FlyDurabilityHandler(config.noFlightDurability(),
|
||||
nbtEditor, durabilityManager), this);
|
||||
nbtEditor, durabilityManager), this);
|
||||
final Listener creationListener =
|
||||
config.craftingInSmithingTable() ?
|
||||
new SmithingTableCraftHandler(this, nbtEditor, durabilityManager, config) :
|
||||
new AnvilHandler(this, nbtEditor, durabilityManager, config);
|
||||
config.craftingInSmithingTable() ?
|
||||
new SmithingTableCraftHandler(this, nbtEditor, durabilityManager, config) :
|
||||
new AnvilHandler(this, nbtEditor, durabilityManager, config);
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(creationListener, this);
|
||||
if (config.allowUpgradeToNetherite())
|
||||
if (config.allowUpgradeToNetherite()) {
|
||||
Bukkit.getPluginManager()
|
||||
.registerEvents(new NetheriteUpgradeListener(this, nbtEditor, durabilityManager, config), this);
|
||||
.registerEvents(new NetheriteUpgradeListener(this, nbtEditor, durabilityManager, config), this);
|
||||
}
|
||||
|
||||
if (config.dropNetheriteAsChestplate())
|
||||
if (config.dropNetheriteAsChestplate()) {
|
||||
Bukkit.getPluginManager().registerEvents(new ItemDropListener(nbtEditor), this);
|
||||
}
|
||||
|
||||
// Log all allowed enchantments.
|
||||
myLogger(Level.INFO, ("Allowed enchantments:"));
|
||||
for (final Enchantment enchantment : config.allowedEnchantments())
|
||||
myLogger(Level.INFO, " - " + enchantment.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
myLogger(Level.WARNING, "Plugin in uninstall mode!");
|
||||
Bukkit.getPluginManager().registerEvents(new Uninstaller(this, nbtEditor), this);
|
||||
}
|
||||
}
|
||||
|
||||
public MinecraftVersion getMinecraftVersion()
|
||||
{
|
||||
public MinecraftVersion getMinecraftVersion() {
|
||||
return minecraftVersion;
|
||||
}
|
||||
|
||||
public Messages getMyMessages()
|
||||
{
|
||||
public Messages getMyMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public NBTEditor getNbtEditor()
|
||||
{
|
||||
public NBTEditor getNbtEditor() {
|
||||
return nbtEditor;
|
||||
}
|
||||
|
||||
private void readMessages()
|
||||
{
|
||||
private void readMessages() {
|
||||
// Shouldn't be used.
|
||||
armorTierNames.put(ArmorTier.NONE, new ArmorTierName("NONE", "NONE"));
|
||||
|
||||
armorTierNames.put(ArmorTier.LEATHER, new ArmorTierName(messages.getString(Message.TIER_LEATHER),
|
||||
messages.getString(Message.TIER_SHORT_LEATHER)));
|
||||
messages.getString(Message.TIER_SHORT_LEATHER)));
|
||||
armorTierNames.put(ArmorTier.GOLD, new ArmorTierName(messages.getString(Message.TIER_GOLD),
|
||||
messages.getString(Message.TIER_SHORT_GOLD)));
|
||||
messages.getString(Message.TIER_SHORT_GOLD)));
|
||||
armorTierNames.put(ArmorTier.CHAIN, new ArmorTierName(messages.getString(Message.TIER_CHAIN),
|
||||
messages.getString(Message.TIER_SHORT_CHAIN)));
|
||||
messages.getString(Message.TIER_SHORT_CHAIN)));
|
||||
armorTierNames.put(ArmorTier.IRON, new ArmorTierName(messages.getString(Message.TIER_IRON),
|
||||
messages.getString(Message.TIER_SHORT_IRON)));
|
||||
messages.getString(Message.TIER_SHORT_IRON)));
|
||||
armorTierNames.put(ArmorTier.DIAMOND, new ArmorTierName(messages.getString(Message.TIER_DIAMOND),
|
||||
messages.getString(Message.TIER_SHORT_DIAMOND)));
|
||||
messages.getString(Message.TIER_SHORT_DIAMOND)));
|
||||
armorTierNames.put(ArmorTier.NETHERITE, new ArmorTierName(messages.getString(Message.TIER_NETHERITE),
|
||||
messages.getString(Message.TIER_SHORT_NETHERITE)));
|
||||
messages.getString(Message.TIER_SHORT_NETHERITE)));
|
||||
}
|
||||
|
||||
public boolean playerHasCraftPerm(HumanEntity player, ArmorTier armorTier)
|
||||
{
|
||||
public boolean playerHasCraftPerm(HumanEntity player, ArmorTier armorTier) {
|
||||
return getConfigLoader().bypassCraftPerm() ||
|
||||
player.hasPermission("armoredelytra.craft." + ArmorTier.getName(armorTier));
|
||||
player.hasPermission("armoredelytra.craft." + ArmorTier.getName(armorTier));
|
||||
}
|
||||
|
||||
public boolean playerHasWearPerm(HumanEntity player, ArmorTier armorTier)
|
||||
{
|
||||
public boolean playerHasWearPerm(HumanEntity player, ArmorTier armorTier) {
|
||||
return getConfigLoader().bypassWearPerm() ||
|
||||
player.hasPermission("armoredelytra.wear." + ArmorTier.getName(armorTier));
|
||||
player.hasPermission("armoredelytra.wear." + ArmorTier.getName(armorTier));
|
||||
}
|
||||
|
||||
// Returns the config handler.
|
||||
public ConfigLoader getConfigLoader()
|
||||
{
|
||||
public ConfigLoader getConfigLoader() {
|
||||
return config;
|
||||
}
|
||||
|
||||
// Send a message to a player in a specific color.
|
||||
public void messagePlayer(HumanEntity player, ChatColor color, String str)
|
||||
{
|
||||
public void messagePlayer(HumanEntity player, ChatColor color, String str) {
|
||||
player.sendMessage(color + str);
|
||||
}
|
||||
|
||||
// Send a message to a player.
|
||||
public void messagePlayer(HumanEntity player, String str)
|
||||
{
|
||||
public void messagePlayer(HumanEntity player, String str) {
|
||||
messagePlayer(player, ChatColor.WHITE, str);
|
||||
}
|
||||
|
||||
private String getMessageWithTierNames(final Message message, final ArmorTier armorTier)
|
||||
{
|
||||
private String getMessageWithTierNames(final Message message, final ArmorTier armorTier) {
|
||||
ArmorTierName tierName = armorTierNames.get(armorTier);
|
||||
return getMyMessages().getString(message,
|
||||
tierName.getLongName(),
|
||||
tierName.getShortName());
|
||||
tierName.getLongName(),
|
||||
tierName.getShortName());
|
||||
}
|
||||
|
||||
// Send the usageDeniedMessage message to the player.
|
||||
public void usageDeniedMessage(HumanEntity player, ArmorTier armorTier)
|
||||
{
|
||||
public void usageDeniedMessage(HumanEntity player, ArmorTier armorTier) {
|
||||
final String message = getMessageWithTierNames(Message.MESSAGES_USAGEDENIED, armorTier);
|
||||
if (!message.equals("NONE"))
|
||||
if (!message.equals("NONE")) {
|
||||
messagePlayer(player, ChatColor.RED, message);
|
||||
}
|
||||
}
|
||||
|
||||
// Send the elytraReceivedMessage message to the player.
|
||||
public void elytraReceivedMessage(HumanEntity player, ArmorTier armorTier)
|
||||
{
|
||||
public void elytraReceivedMessage(HumanEntity player, ArmorTier armorTier) {
|
||||
final String message = getMessageWithTierNames(Message.MESSAGES_ELYTRARECEIVED, armorTier);
|
||||
if (!message.equals("NONE"))
|
||||
if (!message.equals("NONE")) {
|
||||
messagePlayer(player, ChatColor.GREEN, message);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendNoGivePermissionMessage(HumanEntity player, ArmorTier armorTier)
|
||||
{
|
||||
public void sendNoGivePermissionMessage(HumanEntity player, ArmorTier armorTier) {
|
||||
final String message = getMessageWithTierNames(Message.MESSAGES_NOGIVEPERMISSION, armorTier);
|
||||
messagePlayer(player, ChatColor.RED, message);
|
||||
}
|
||||
|
||||
public @Nullable List<String> getElytraLore(ArmorTier armorTier)
|
||||
{
|
||||
public @Nullable List<String> getElytraLore(ArmorTier armorTier) {
|
||||
final String message = ChatColor.stripColor(getMessageWithTierNames(Message.MESSAGES_LORE, armorTier));
|
||||
return message.equals("NONE") ? null : Collections.singletonList(message);
|
||||
}
|
||||
|
||||
// Print a string to the log.
|
||||
public void myLogger(Level level, String str)
|
||||
{
|
||||
public void myLogger(Level level, String str) {
|
||||
Bukkit.getLogger().log(level, "[" + getName() + "] " + str);
|
||||
}
|
||||
|
||||
// Log message that only gets printed when debugging is enabled in the config file.
|
||||
public void debugMsg(Level level, String str)
|
||||
{
|
||||
if (config.enableDebug())
|
||||
public void debugMsg(Level level, String str) {
|
||||
if (config.enableDebug()) {
|
||||
myLogger(level, str);
|
||||
}
|
||||
}
|
||||
|
||||
// Give the provided player the provided item.
|
||||
public void giveArmoredElytraToPlayer(HumanEntity player, ItemStack item)
|
||||
{
|
||||
if (item != null)
|
||||
public void giveArmoredElytraToPlayer(HumanEntity player, ItemStack item) {
|
||||
if (item != null) {
|
||||
player.getInventory().addItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
public UpdateManager getUpdateManager()
|
||||
{
|
||||
public UpdateManager getUpdateManager() {
|
||||
return updateManager;
|
||||
}
|
||||
|
||||
public static ArmoredElytra getInstance()
|
||||
{
|
||||
public static ArmoredElytra getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public String getArmoredElytraName(ArmorTier tier)
|
||||
{
|
||||
if (tier == null)
|
||||
{
|
||||
public String getArmoredElytraName(ArmorTier tier) {
|
||||
if (tier == null) {
|
||||
getLogger().log(Level.INFO, "ArmorTier was null! Failed to obtain proper string!");
|
||||
return "NULL";
|
||||
}
|
||||
|
@ -24,17 +24,14 @@ import org.bukkit.inventory.meta.ItemMeta;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
||||
{
|
||||
public class AnvilHandler extends ArmoredElytraHandler implements Listener {
|
||||
protected AnvilHandler(ArmoredElytra plugin, boolean creationEnabled,
|
||||
NBTEditor nbtEditor, DurabilityManager durabilityManager, ConfigLoader config)
|
||||
{
|
||||
NBTEditor nbtEditor, DurabilityManager durabilityManager, ConfigLoader config) {
|
||||
super(plugin, creationEnabled, nbtEditor, durabilityManager, config);
|
||||
}
|
||||
|
||||
public AnvilHandler(ArmoredElytra plugin, NBTEditor nbtEditor,
|
||||
DurabilityManager durabilityManager, ConfigLoader config)
|
||||
{
|
||||
DurabilityManager durabilityManager, ConfigLoader config) {
|
||||
super(plugin, true, nbtEditor, durabilityManager, config);
|
||||
}
|
||||
|
||||
@ -48,100 +45,109 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
||||
// Ignoring:
|
||||
// - Elytra (not armored) + !chestplate -> None
|
||||
// - * + * -> None
|
||||
private Action isValidInput(ArmorTier itemOneTier, ItemStack itemOne, ItemStack itemTwo)
|
||||
{
|
||||
if (itemOne == null || itemTwo == null)
|
||||
private Action isValidInput(ArmorTier itemOneTier, ItemStack itemOne, ItemStack itemTwo) {
|
||||
if (itemOne == null || itemTwo == null) {
|
||||
return Action.NONE;
|
||||
}
|
||||
|
||||
if (itemOne.getType() != Material.ELYTRA)
|
||||
if (itemOne.getType() != Material.ELYTRA) {
|
||||
return Action.NONE;
|
||||
}
|
||||
|
||||
final Material matTwo = itemTwo.getType();
|
||||
|
||||
// If the elytra is to be combined with chest armor...
|
||||
if (Util.isChestPlate(matTwo))
|
||||
if (Util.isChestPlate(matTwo)) {
|
||||
return creationEnabled ? Action.CREATE : Action.NONE;
|
||||
}
|
||||
|
||||
if (itemOneTier != ArmorTier.NONE)
|
||||
{
|
||||
if (itemOneTier != ArmorTier.NONE) {
|
||||
// If the armored elytra is to be enchanted using an enchanted book...
|
||||
if (matTwo == Material.ENCHANTED_BOOK)
|
||||
if (matTwo == Material.ENCHANTED_BOOK) {
|
||||
return config.allowAddingEnchantments() ? Action.ENCHANT : Action.BLOCK;
|
||||
}
|
||||
|
||||
// If the armored elytra is to be repaired using its repair item...
|
||||
if (ArmorTier.getRepairItem(itemOneTier) == matTwo)
|
||||
if (ArmorTier.getRepairItem(itemOneTier) == matTwo) {
|
||||
return durabilityManager.getRealDurability(itemOne, itemOneTier) == 0 ? Action.BLOCK : Action.REPAIR;
|
||||
}
|
||||
|
||||
// If the armored elytra is to be combined with another armored elytra of the same tier...
|
||||
if (nbtEditor.getArmorTier(itemTwo) == itemOneTier)
|
||||
if (nbtEditor.getArmorTier(itemTwo) == itemOneTier) {
|
||||
return creationEnabled ? Action.COMBINE : Action.NONE;
|
||||
}
|
||||
|
||||
// If the armored elytra is not of the leather tier, but itemTwo is leather,
|
||||
// Pick the block action, as that would repair the elytra by default (vanilla).
|
||||
// Also block Armored Elytra + Elytra and Elytra + Membrane
|
||||
if (itemOneTier != ArmorTier.LEATHER && matTwo == Material.LEATHER || matTwo == Material.ELYTRA ||
|
||||
matTwo.equals(XMaterial.PHANTOM_MEMBRANE.parseMaterial()))
|
||||
matTwo.equals(XMaterial.PHANTOM_MEMBRANE.parseMaterial())) {
|
||||
return Action.BLOCK;
|
||||
}
|
||||
}
|
||||
return Action.NONE;
|
||||
}
|
||||
|
||||
// Handle all anvil related stuff for this plugin.
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
private void onAnvilInventoryOpen(PrepareAnvilEvent event)
|
||||
{
|
||||
if (!(event.getView().getPlayer() instanceof Player player))
|
||||
private void onAnvilInventoryOpen(PrepareAnvilEvent event) {
|
||||
if (!(event.getView().getPlayer() instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack itemA = event.getInventory().getItem(0);
|
||||
ItemStack itemB = event.getInventory().getItem(1);
|
||||
|
||||
if (itemA != null && itemB != null)
|
||||
// If itemB is the (armored) elytra, while itemA isn't, switch itemA and itemB.
|
||||
if (itemB.getType() == Material.ELYTRA && itemA.getType() != Material.ELYTRA)
|
||||
{
|
||||
// If itemB is the (armored) elytra, while itemA isn't, switch itemA and itemB.
|
||||
{
|
||||
if (itemB.getType() == Material.ELYTRA && itemA.getType() != Material.ELYTRA) {
|
||||
ItemStack tmp = itemA;
|
||||
itemA = itemB;
|
||||
itemB = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// If one of the input items is null and the other an armored elytra, remove the result.
|
||||
// This prevents some naming issues.
|
||||
if ((itemA == null ^ itemB == null) &&
|
||||
nbtEditor.getArmorTier(itemA == null ? itemB : itemA) != ArmorTier.NONE)
|
||||
nbtEditor.getArmorTier(itemA == null ? itemB : itemA) != ArmorTier.NONE) {
|
||||
event.setResult(null);
|
||||
}
|
||||
|
||||
if (itemA == null || itemB == null)
|
||||
if (itemA == null || itemB == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ArmorTier currentArmorTier = nbtEditor.getArmorTier(itemA);
|
||||
final Action action = isValidInput(currentArmorTier, itemA, itemB);
|
||||
|
||||
if (action == Action.NONE)
|
||||
if (action == Action.NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ArmorTier newArmorTier;
|
||||
if (action == Action.CREATE)
|
||||
if (action == Action.CREATE) {
|
||||
newArmorTier = Util.armorToTier(itemB);
|
||||
else if (action == Action.COMBINE)
|
||||
} else if (action == Action.COMBINE) {
|
||||
newArmorTier = nbtEditor.getArmorTier(itemB);
|
||||
else
|
||||
} else {
|
||||
newArmorTier = currentArmorTier;
|
||||
}
|
||||
|
||||
final @Nullable String name = getElytraResultName(itemA, action, currentArmorTier, newArmorTier,
|
||||
event.getInventory().getRenameText());
|
||||
event.getInventory().getRenameText());
|
||||
|
||||
final @Nullable ItemStack result =
|
||||
!plugin.playerHasCraftPerm(player, newArmorTier) ? null :
|
||||
switch (action)
|
||||
{
|
||||
case REPAIR -> armoredElytraBuilder.repair(itemA, itemB, name);
|
||||
case ENCHANT -> armoredElytraBuilder.enchant(itemA, itemB, name);
|
||||
case COMBINE, CREATE -> armoredElytraBuilder.combine(itemA, itemB, newArmorTier, name);
|
||||
case BLOCK -> null;
|
||||
//noinspection ConstantConditions
|
||||
case NONE -> itemA;
|
||||
};
|
||||
!plugin.playerHasCraftPerm(player, newArmorTier) ? null :
|
||||
switch (action) {
|
||||
case REPAIR -> armoredElytraBuilder.repair(itemA, itemB, name);
|
||||
case ENCHANT -> armoredElytraBuilder.enchant(itemA, itemB, name);
|
||||
case COMBINE, CREATE -> armoredElytraBuilder.combine(itemA, itemB, newArmorTier, name);
|
||||
case BLOCK -> null;
|
||||
//noinspection ConstantConditions
|
||||
case NONE -> itemA;
|
||||
};
|
||||
|
||||
event.setResult(result);
|
||||
player.updateInventory();
|
||||
@ -149,14 +155,14 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
||||
|
||||
private @Nullable String getElytraResultName(final ItemStack baseItem, final Action action,
|
||||
final ArmorTier currentArmorTier, final ArmorTier newArmorTier,
|
||||
final String renameText)
|
||||
{
|
||||
final String renameText) {
|
||||
final String currentTierName = plugin.getArmoredElytraName(currentArmorTier);
|
||||
final String tierName = plugin.getArmoredElytraName(newArmorTier);
|
||||
|
||||
if (renameText == null || !config.allowRenaming() ||
|
||||
ChatColor.stripColor(currentTierName).equals(ChatColor.stripColor(renameText)))
|
||||
ChatColor.stripColor(currentTierName).equals(ChatColor.stripColor(renameText))) {
|
||||
return tierName;
|
||||
}
|
||||
|
||||
final ItemMeta meta = baseItem.getItemMeta();
|
||||
final String currentName = meta == null ? null : meta.getDisplayName();
|
||||
@ -165,36 +171,35 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
||||
// (so it's named properly) or when the current name is already the tier name (just returning the current
|
||||
// name would strip the tier's color in this case).
|
||||
if ((action == Action.CREATE && renameText.equals("")) ||
|
||||
ChatColor.stripColor(tierName).equals(ChatColor.stripColor(renameText)))
|
||||
ChatColor.stripColor(tierName).equals(ChatColor.stripColor(renameText))) {
|
||||
return tierName;
|
||||
}
|
||||
|
||||
return renameText.equals("") ? currentName : renameText;
|
||||
}
|
||||
|
||||
// Let the player take items out of the anvil.
|
||||
@EventHandler
|
||||
public void onInventoryClick(InventoryClickEvent e)
|
||||
{
|
||||
if (e.getRawSlot() != 2 || !(e.getWhoClicked() instanceof Player player))
|
||||
public void onInventoryClick(InventoryClickEvent e) {
|
||||
if (e.getRawSlot() != 2 || !(e.getWhoClicked() instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the event was a player who interacted with an anvil.
|
||||
if (e.getView().getType() != InventoryType.ANVIL)
|
||||
if (e.getView().getType() != InventoryType.ANVIL) {
|
||||
return;
|
||||
}
|
||||
|
||||
AnvilInventory anvilInventory;
|
||||
// Try to cast inventory being used in the event to an anvil inventory.
|
||||
// This will throw a ClassCastException when a CraftInventoryCustom is used.
|
||||
try
|
||||
{
|
||||
try {
|
||||
anvilInventory = (AnvilInventory) e.getInventory();
|
||||
}
|
||||
catch (ClassCastException exception)
|
||||
{
|
||||
} catch (ClassCastException exception) {
|
||||
// Print warning to console and exit onInventoryClick event (no support for
|
||||
// custom inventories as they are usually used for GUI's).
|
||||
plugin.debugMsg(Level.WARNING, "Could not cast inventory to anvilInventory for player " + player.getName()
|
||||
+ "! Armored Elytras cannot be crafted!");
|
||||
+ "! Armored Elytras cannot be crafted!");
|
||||
exception.printStackTrace();
|
||||
return;
|
||||
}
|
||||
@ -203,15 +208,14 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
||||
final @Nullable ItemStack item1 = anvilInventory.getItem(1);
|
||||
final @Nullable ItemStack item2 = anvilInventory.getItem(2);
|
||||
|
||||
if (item0 != null && item1 != null && item2 != null && item2.getType() == Material.ELYTRA)
|
||||
{
|
||||
if (item0 != null && item1 != null && item2 != null && item2.getType() == Material.ELYTRA) {
|
||||
final ArmorTier armortier = nbtEditor.getArmorTier(anvilInventory.getItem(2));
|
||||
|
||||
// If there's an armored elytra in the final slot...
|
||||
if (armortier != ArmorTier.NONE && plugin.playerHasCraftPerm(player, armortier))
|
||||
{
|
||||
if (!giveItemToPlayer(player, item2, e.isShiftClick()))
|
||||
if (armortier != ArmorTier.NONE && plugin.playerHasCraftPerm(player, armortier)) {
|
||||
if (!giveItemToPlayer(player, item2, e.isShiftClick())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clean the anvil's inventory after transferring the items.
|
||||
anvilInventory.clear();
|
||||
|
@ -15,8 +15,7 @@ import javax.annotation.CheckReturnValue;
|
||||
*
|
||||
* @author Pim
|
||||
*/
|
||||
abstract class ArmoredElytraHandler
|
||||
{
|
||||
abstract class ArmoredElytraHandler {
|
||||
protected final ArmoredElytra plugin;
|
||||
protected final boolean creationEnabled;
|
||||
protected final ConfigLoader config;
|
||||
@ -26,8 +25,7 @@ abstract class ArmoredElytraHandler
|
||||
|
||||
protected ArmoredElytraHandler(ArmoredElytra plugin, boolean creationEnabled, NBTEditor nbtEditor,
|
||||
DurabilityManager durabilityManager, ConfigLoader config,
|
||||
ArmoredElytraBuilder armoredElytraBuilder)
|
||||
{
|
||||
ArmoredElytraBuilder armoredElytraBuilder) {
|
||||
this.plugin = plugin;
|
||||
this.creationEnabled = creationEnabled;
|
||||
this.nbtEditor = nbtEditor;
|
||||
@ -37,10 +35,9 @@ abstract class ArmoredElytraHandler
|
||||
}
|
||||
|
||||
protected ArmoredElytraHandler(ArmoredElytra plugin, boolean creationEnabled, NBTEditor nbtEditor,
|
||||
DurabilityManager durabilityManager, ConfigLoader config)
|
||||
{
|
||||
DurabilityManager durabilityManager, ConfigLoader config) {
|
||||
this(plugin, creationEnabled, nbtEditor, durabilityManager, config,
|
||||
new ArmoredElytraBuilder(nbtEditor, durabilityManager, config, plugin));
|
||||
new ArmoredElytraBuilder(nbtEditor, durabilityManager, config, plugin));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,17 +50,16 @@ abstract class ArmoredElytraHandler
|
||||
* @return True if the item could be given to the player, otherwise false (e.g. when their inventory is full).
|
||||
*/
|
||||
@CheckReturnValue
|
||||
protected boolean giveItemToPlayer(final Player player, final ItemStack item, final boolean direct)
|
||||
{
|
||||
if (direct)
|
||||
{
|
||||
protected boolean giveItemToPlayer(final Player player, final ItemStack item, final boolean direct) {
|
||||
if (direct) {
|
||||
// If the player's inventory is full, don't do anything.
|
||||
if (player.getInventory().firstEmpty() == -1)
|
||||
if (player.getInventory().firstEmpty() == -1) {
|
||||
return false;
|
||||
}
|
||||
player.getInventory().addItem(item);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
player.setItemOnCursor(item);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -20,51 +20,41 @@ import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class CommandHandler implements CommandExecutor
|
||||
{
|
||||
public class CommandHandler implements CommandExecutor {
|
||||
private final ArmoredElytra plugin;
|
||||
private static Field BY_KEY_FIELD;
|
||||
private final ArmoredElytraBuilder armoredElytraBuilder;
|
||||
|
||||
public CommandHandler(ArmoredElytra plugin, NBTEditor nbtEditor, DurabilityManager durabilityManager)
|
||||
{
|
||||
public CommandHandler(ArmoredElytra plugin, NBTEditor nbtEditor, DurabilityManager durabilityManager) {
|
||||
this.plugin = plugin;
|
||||
armoredElytraBuilder = new ArmoredElytraBuilder(nbtEditor, durabilityManager, plugin.getConfigLoader(), plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args)
|
||||
{
|
||||
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
|
||||
Player player;
|
||||
|
||||
if (sender instanceof Player)
|
||||
{
|
||||
if (sender instanceof Player) {
|
||||
player = (Player) sender;
|
||||
|
||||
if (plugin.getConfigLoader().uninstallMode())
|
||||
{
|
||||
if (plugin.getConfigLoader().uninstallMode()) {
|
||||
plugin.messagePlayer(player, plugin.getMyMessages().getString(Message.MESSAGES_UNINSTALLMODE));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cmd.getName().equalsIgnoreCase("ArmoredElytra"))
|
||||
if (args.length == 1 || args.length == 2)
|
||||
{
|
||||
if (cmd.getName().equalsIgnoreCase("ArmoredElytra")) {
|
||||
if (args.length == 1 || args.length == 2) {
|
||||
ItemStack newElytra = null;
|
||||
String tier = null;
|
||||
Player receiver;
|
||||
boolean allowed = false;
|
||||
|
||||
if (args.length == 1)
|
||||
{
|
||||
if (args.length == 1) {
|
||||
receiver = player;
|
||||
tier = args[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
receiver = Bukkit.getPlayer(args[0]);
|
||||
if (receiver == null)
|
||||
{
|
||||
if (receiver == null) {
|
||||
plugin.messagePlayer(player, ChatColor.RED, "Player \"" + args[0] + "\" not found!");
|
||||
return true;
|
||||
}
|
||||
@ -72,56 +62,50 @@ public class CommandHandler implements CommandExecutor
|
||||
}
|
||||
|
||||
ArmorTier armorTier = ArmorTier.valueOfName(tier.toLowerCase());
|
||||
if (armorTier != null)
|
||||
if (armorTier != null) {
|
||||
allowed = player.hasPermission("armoredelytra.give." + ArmorTier.getName(armorTier));
|
||||
else
|
||||
{
|
||||
} else {
|
||||
plugin.messagePlayer(player, plugin.getMyMessages()
|
||||
.getString(Message.MESSAGES_UNSUPPORTEDTIER));
|
||||
.getString(Message.MESSAGES_UNSUPPORTEDTIER));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (allowed)
|
||||
{
|
||||
if (allowed) {
|
||||
plugin.elytraReceivedMessage(receiver, armorTier);
|
||||
plugin.giveArmoredElytraToPlayer(receiver, armoredElytraBuilder.newArmoredElytra(armorTier));
|
||||
}
|
||||
else
|
||||
} else {
|
||||
plugin.sendNoGivePermissionMessage(player, armorTier);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (plugin.getConfigLoader().uninstallMode())
|
||||
{
|
||||
}
|
||||
} else {
|
||||
if (plugin.getConfigLoader().uninstallMode()) {
|
||||
plugin.myLogger(Level.INFO, "Plugin in uninstall mode! New Armored Elytras are not allowed!");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 1 &&
|
||||
(args[0].equalsIgnoreCase("listAvailableEnchantments") ||
|
||||
args[0].equalsIgnoreCase("listEnchantments") ||
|
||||
args[0].equalsIgnoreCase("enchantments")))
|
||||
{
|
||||
(args[0].equalsIgnoreCase("listAvailableEnchantments") ||
|
||||
args[0].equalsIgnoreCase("listEnchantments") ||
|
||||
args[0].equalsIgnoreCase("enchantments"))) {
|
||||
listAvailableEnchantments();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 2)
|
||||
{
|
||||
if (args.length == 2) {
|
||||
final String tier = args[1];
|
||||
player = Bukkit.getPlayer(args[0]);
|
||||
if (player != null)
|
||||
{
|
||||
if (player != null) {
|
||||
ArmorTier armorTier = ArmorTier.valueOfName(tier.toLowerCase());
|
||||
if (armorTier == null)
|
||||
if (armorTier == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
plugin.elytraReceivedMessage(player, armorTier);
|
||||
plugin.giveArmoredElytraToPlayer(player, armoredElytraBuilder.newArmoredElytra(armorTier));
|
||||
plugin.myLogger(Level.INFO, ("Giving an armored elytra of the " + ArmorTier.getArmor(armorTier) +
|
||||
" armor tier to player " + player.getName()));
|
||||
" armor tier to player " + player.getName()));
|
||||
return true;
|
||||
}
|
||||
plugin.myLogger(Level.INFO, ("Player " + args[1] + " not found!"));
|
||||
@ -131,28 +115,22 @@ public class CommandHandler implements CommandExecutor
|
||||
return false;
|
||||
}
|
||||
|
||||
private void listAvailableEnchantments()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (BY_KEY_FIELD == null)
|
||||
{
|
||||
private void listAvailableEnchantments() {
|
||||
try {
|
||||
if (BY_KEY_FIELD == null) {
|
||||
BY_KEY_FIELD = Enchantment.class.getDeclaredField("byKey");
|
||||
BY_KEY_FIELD.setAccessible(true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final Map<NamespacedKey, Enchantment> byKey = (Map<NamespacedKey, Enchantment>) BY_KEY_FIELD.get(null);
|
||||
@SuppressWarnings("unchecked") final Map<NamespacedKey, Enchantment> byKey = (Map<NamespacedKey, Enchantment>) BY_KEY_FIELD.get(null);
|
||||
|
||||
final StringBuilder sb = new StringBuilder("\nAvailable enchantments: \n");
|
||||
byKey.keySet().stream()
|
||||
.map(NamespacedKey::toString).sorted()
|
||||
.forEach(name -> sb.append(" - ").append(name).append("\n"));
|
||||
.map(NamespacedKey::toString).sorted()
|
||||
.forEach(name -> sb.append(" - ").append(name).append("\n"));
|
||||
|
||||
Bukkit.getLogger().info(sb.toString());
|
||||
}
|
||||
catch (NoSuchFieldException | IllegalAccessException e)
|
||||
{
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new RuntimeException("Failed to get registered enchantments!", e);
|
||||
}
|
||||
}
|
||||
|
@ -26,122 +26,122 @@ import org.bukkit.inventory.ItemStack;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
public class EventHandlers implements Listener
|
||||
{
|
||||
public class EventHandlers implements Listener {
|
||||
private final Random random = new Random();
|
||||
private final ArmoredElytra plugin;
|
||||
private final NBTEditor nbtEditor;
|
||||
private final DurabilityManager durabilityManager;
|
||||
|
||||
public EventHandlers(ArmoredElytra plugin, NBTEditor nbtEditor, DurabilityManager durabilityManager)
|
||||
{
|
||||
public EventHandlers(ArmoredElytra plugin, NBTEditor nbtEditor, DurabilityManager durabilityManager) {
|
||||
this.plugin = plugin;
|
||||
this.nbtEditor = nbtEditor;
|
||||
this.durabilityManager = durabilityManager;
|
||||
initializeArmorEquipEvent();
|
||||
}
|
||||
|
||||
private void initializeArmorEquipEvent()
|
||||
{
|
||||
private void initializeArmorEquipEvent() {
|
||||
Bukkit.getPluginManager().registerEvents(new ArmorListener(new ArrayList<>()), plugin);
|
||||
Bukkit.getPluginManager().registerEvents(new DispenserArmorListener(), plugin);
|
||||
}
|
||||
|
||||
// Make sure the player has the correct permission and that the item is not
|
||||
// broken.
|
||||
private AllowedToWearEnum isAllowedToWear(ItemStack elytra, Player player, ArmorTier armorTier)
|
||||
{
|
||||
if (armorTier.equals(ArmorTier.NONE))
|
||||
private AllowedToWearEnum isAllowedToWear(ItemStack elytra, Player player, ArmorTier armorTier) {
|
||||
if (armorTier.equals(ArmorTier.NONE)) {
|
||||
return AllowedToWearEnum.ALLOWED;
|
||||
if (Util.isBroken(elytra))
|
||||
}
|
||||
if (Util.isBroken(elytra)) {
|
||||
return AllowedToWearEnum.BROKEN;
|
||||
if (!plugin.playerHasWearPerm(player, armorTier))
|
||||
}
|
||||
if (!plugin.playerHasWearPerm(player, armorTier)) {
|
||||
return AllowedToWearEnum.NOPERMISSION;
|
||||
}
|
||||
return AllowedToWearEnum.ALLOWED;
|
||||
}
|
||||
|
||||
// Handle armored elytra durability loss.
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerDamage(EntityDamageEvent e)
|
||||
{
|
||||
if (!(e.getEntity() instanceof final Player p))
|
||||
public void onPlayerDamage(EntityDamageEvent e) {
|
||||
if (!(e.getEntity() instanceof final Player p)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ItemStack elytra = p.getInventory().getChestplate();
|
||||
if (elytra == null)
|
||||
if (elytra == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ArmorTier armorTier = nbtEditor.getArmorTier(elytra);
|
||||
if (armorTier == ArmorTier.NONE)
|
||||
if (armorTier == ArmorTier.NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
final DamageCause cause = e.getCause();
|
||||
// The elytra doesn't receive any damage for these causes:
|
||||
if (cause == DamageCause.DROWNING || cause == DamageCause.STARVATION || cause == DamageCause.SUFFOCATION ||
|
||||
cause == DamageCause.SUICIDE || cause == DamageCause.FLY_INTO_WALL || cause == DamageCause.POISON)
|
||||
cause == DamageCause.SUICIDE || cause == DamageCause.FLY_INTO_WALL || cause == DamageCause.POISON) {
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean removeDurability;
|
||||
if (elytra.containsEnchantment(Enchantment.DURABILITY))
|
||||
{
|
||||
if (elytra.containsEnchantment(Enchantment.DURABILITY)) {
|
||||
final int randomInt = random.nextInt(101);
|
||||
final int enchantLevel = elytra.getEnchantmentLevel(Enchantment.DURABILITY);
|
||||
// Formula taken from: https://minecraft.fandom.com/wiki/Unbreaking#Usage
|
||||
final float removeDurabilityChance = 60 + 40f / (enchantLevel + 1);
|
||||
removeDurability = randomInt <= removeDurabilityChance;
|
||||
}
|
||||
else
|
||||
} else {
|
||||
removeDurability = true;
|
||||
}
|
||||
|
||||
// Even when we don't subtract durability, we still want to update the durability, so just subtract 0.
|
||||
final int durabilityLoss = removeDurability ? (int) Math.max(1, e.getDamage() / 4) : 0;
|
||||
final int newDurability = durabilityManager.removeDurability(elytra, durabilityLoss, armorTier);
|
||||
if (durabilityManager.isBroken(newDurability, armorTier))
|
||||
if (durabilityManager.isBroken(newDurability, armorTier)) {
|
||||
Util.moveChestplateToInventory(p);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onMending(PlayerItemMendEvent e)
|
||||
{
|
||||
public void onMending(PlayerItemMendEvent e) {
|
||||
final ArmorTier armorTier = nbtEditor.getArmorTier(e.getItem());
|
||||
if (armorTier == ArmorTier.NONE)
|
||||
if (armorTier == ArmorTier.NONE) {
|
||||
return;
|
||||
}
|
||||
final int newDurability = durabilityManager.removeDurability(e.getItem(), -e.getRepairAmount(), armorTier);
|
||||
|
||||
// Apply it again a tick later, so we can override the durability of the armored elytra without
|
||||
// interfering with the player XP change event that depends on the success of this one.
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () ->
|
||||
durabilityManager.setDurability(e.getItem(), newDurability, armorTier), 1);
|
||||
durabilityManager.setDurability(e.getItem(), newDurability, armorTier), 1);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEquip(ArmorEquipEvent e)
|
||||
{
|
||||
public void onEquip(ArmorEquipEvent e) {
|
||||
if (e.getMethod().equals(ArmorEquipEvent.EquipMethod.DEATH) ||
|
||||
e.getMethod().equals(ArmorEquipEvent.EquipMethod.BROKE))
|
||||
e.getMethod().equals(ArmorEquipEvent.EquipMethod.BROKE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!e.getType().equals(ArmorType.CHESTPLATE) ||
|
||||
e.getNewArmorPiece() == null ||
|
||||
!e.getNewArmorPiece().getType().equals(Material.ELYTRA))
|
||||
e.getNewArmorPiece() == null ||
|
||||
!e.getNewArmorPiece().getType().equals(Material.ELYTRA)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ArmorTier armorTier = nbtEditor.getArmorTier(e.getNewArmorPiece());
|
||||
final AllowedToWearEnum allowed = isAllowedToWear(e.getNewArmorPiece(), e.getPlayer(), armorTier);
|
||||
switch (allowed)
|
||||
{
|
||||
case ALLOWED:
|
||||
break;
|
||||
case BROKEN:
|
||||
switch (allowed) {
|
||||
case BROKEN -> {
|
||||
plugin.messagePlayer(e.getPlayer(), plugin.getMyMessages().getString(Message.MESSAGES_REPAIRNEEDED));
|
||||
e.setCancelled(true);
|
||||
break;
|
||||
case NOPERMISSION:
|
||||
}
|
||||
case NOPERMISSION -> {
|
||||
plugin.usageDeniedMessage(e.getPlayer(), armorTier);
|
||||
e.setCancelled(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case ALLOWED, default -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,14 +10,12 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerItemDamageEvent;
|
||||
|
||||
public class FlyDurabilityHandler implements Listener
|
||||
{
|
||||
public class FlyDurabilityHandler implements Listener {
|
||||
private final boolean disableDurability;
|
||||
private final NBTEditor nbtEditor;
|
||||
private final DurabilityManager durabilityManager;
|
||||
|
||||
public FlyDurabilityHandler(boolean disableDurability, NBTEditor nbtEditor, DurabilityManager durabilityManager)
|
||||
{
|
||||
public FlyDurabilityHandler(boolean disableDurability, NBTEditor nbtEditor, DurabilityManager durabilityManager) {
|
||||
this.disableDurability = disableDurability;
|
||||
this.nbtEditor = nbtEditor;
|
||||
this.durabilityManager = durabilityManager;
|
||||
@ -25,26 +23,30 @@ public class FlyDurabilityHandler implements Listener
|
||||
|
||||
// Do not decrease elytra durability while flying.
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onItemDamage(PlayerItemDamageEvent e)
|
||||
{
|
||||
if (e.getItem().getType() != Material.ELYTRA)
|
||||
public void onItemDamage(PlayerItemDamageEvent e) {
|
||||
if (e.getItem().getType() != Material.ELYTRA) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!e.getPlayer().isGliding())
|
||||
if (!e.getPlayer().isGliding()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ArmorTier armorTier = nbtEditor.getArmorTier(e.getItem());
|
||||
if (armorTier == ArmorTier.NONE)
|
||||
if (armorTier == ArmorTier.NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This also cancels durability decrease when it should (i.e. getting hit) while flying,
|
||||
// but that is likely to be rare enough for it to not matter.
|
||||
e.setCancelled(true);
|
||||
if (disableDurability)
|
||||
if (disableDurability) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int newDurability = durabilityManager.removeDurability(e.getItem(), e.getDamage(), armorTier);
|
||||
if (durabilityManager.isBroken(newDurability, armorTier))
|
||||
if (durabilityManager.isBroken(newDurability, armorTier)) {
|
||||
Util.moveChestplateToInventory(e.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,12 +11,10 @@ import org.bukkit.event.entity.ItemSpawnEvent;
|
||||
import org.bukkit.event.inventory.InventoryPickupItemEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class ItemDropListener implements Listener
|
||||
{
|
||||
public class ItemDropListener implements Listener {
|
||||
private final NBTEditor nbtEditor;
|
||||
|
||||
public ItemDropListener(NBTEditor nbtEditor)
|
||||
{
|
||||
public ItemDropListener(NBTEditor nbtEditor) {
|
||||
this.nbtEditor = nbtEditor;
|
||||
}
|
||||
|
||||
@ -29,11 +27,11 @@ public class ItemDropListener implements Listener
|
||||
* @param itemStack The dropped item to analyze.
|
||||
* @return The new item to drop if it should be changed. If no change is required, null is returned.
|
||||
*/
|
||||
private ItemStack getNewDrop(final ItemStack itemStack)
|
||||
{
|
||||
private ItemStack getNewDrop(final ItemStack itemStack) {
|
||||
if (itemStack == null || itemStack.getType() != Material.ELYTRA ||
|
||||
nbtEditor.getArmorTier(itemStack) != ArmorTier.NETHERITE)
|
||||
nbtEditor.getArmorTier(itemStack) != ArmorTier.NETHERITE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final ItemStack newDrop = new ItemStack(Material.NETHERITE_CHESTPLATE, 1);
|
||||
newDrop.setItemMeta(itemStack.getItemMeta());
|
||||
@ -50,11 +48,11 @@ public class ItemDropListener implements Listener
|
||||
* @param itemStack The picked-up item to analyze.
|
||||
* @return The new item to pick up if it should be changed. If no change is required, null is returned.
|
||||
*/
|
||||
private ItemStack getNewPickup(final ItemStack itemStack)
|
||||
{
|
||||
private ItemStack getNewPickup(final ItemStack itemStack) {
|
||||
if (itemStack == null || itemStack.getType() != Material.NETHERITE_CHESTPLATE ||
|
||||
nbtEditor.getArmorTier(itemStack) != ArmorTier.NETHERITE)
|
||||
nbtEditor.getArmorTier(itemStack) != ArmorTier.NETHERITE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final ItemStack newDrop = new ItemStack(Material.ELYTRA, 1);
|
||||
newDrop.setItemMeta(itemStack.getItemMeta());
|
||||
@ -63,26 +61,26 @@ public class ItemDropListener implements Listener
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onDrop(final ItemSpawnEvent event)
|
||||
{
|
||||
public void onDrop(final ItemSpawnEvent event) {
|
||||
final ItemStack newDrop = getNewDrop(event.getEntity().getItemStack());
|
||||
if (newDrop != null)
|
||||
if (newDrop != null) {
|
||||
event.getEntity().setItemStack(newDrop);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onEntityPickup(EntityPickupItemEvent event)
|
||||
{
|
||||
public void onEntityPickup(EntityPickupItemEvent event) {
|
||||
final ItemStack newPickup = getNewPickup(event.getItem().getItemStack());
|
||||
if (newPickup != null)
|
||||
if (newPickup != null) {
|
||||
event.getItem().setItemStack(newPickup);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onInventoryPickup(InventoryPickupItemEvent event)
|
||||
{
|
||||
public void onInventoryPickup(InventoryPickupItemEvent event) {
|
||||
final ItemStack newPickup = getNewPickup(event.getItem().getItemStack());
|
||||
if (newPickup != null)
|
||||
if (newPickup != null) {
|
||||
event.getItem().setItemStack(newPickup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,30 +8,27 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
public class LoginHandler implements Listener
|
||||
{
|
||||
public class LoginHandler implements Listener {
|
||||
private final ArmoredElytra plugin;
|
||||
private final String message;
|
||||
|
||||
public LoginHandler(ArmoredElytra plugin, String message)
|
||||
{
|
||||
public LoginHandler(ArmoredElytra plugin, String message) {
|
||||
this.plugin = plugin;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onLogin(PlayerLoginEvent event)
|
||||
{
|
||||
public void onLogin(PlayerLoginEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (player.hasPermission("armoredElytra.admin"))
|
||||
// Slight delay so the player actually receives the message;
|
||||
new BukkitRunnable()
|
||||
{
|
||||
// Slight delay so the player actually receives the message;
|
||||
{
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
public void run() {
|
||||
plugin.messagePlayer(player, ChatColor.AQUA, message);
|
||||
}
|
||||
}.runTaskLater(plugin, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,43 +14,42 @@ import org.bukkit.inventory.SmithingInventory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class NetheriteUpgradeListener extends SmithingTableListener
|
||||
{
|
||||
public class NetheriteUpgradeListener extends SmithingTableListener {
|
||||
public NetheriteUpgradeListener(final ArmoredElytra plugin, NBTEditor nbtEditor,
|
||||
DurabilityManager durabilityManager, ConfigLoader config)
|
||||
{
|
||||
DurabilityManager durabilityManager, ConfigLoader config) {
|
||||
super(plugin, false, nbtEditor, durabilityManager, config);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSmithingTableUsage(final PrepareSmithingEvent event)
|
||||
{
|
||||
public void onSmithingTableUsage(final PrepareSmithingEvent event) {
|
||||
final SmithingInventory inventory = event.getInventory();
|
||||
final ItemStack[] contents = inventory.getContents();
|
||||
|
||||
final ItemStack itemStackA = contents[0];
|
||||
final ItemStack itemStackB = contents[1];
|
||||
|
||||
if (!validInput(itemStackA, itemStackB))
|
||||
if (!validInput(itemStackA, itemStackB)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!plugin.playerHasCraftPerm(event.getView().getPlayer(), ArmorTier.NETHERITE))
|
||||
if (!plugin.playerHasCraftPerm(event.getView().getPlayer(), ArmorTier.NETHERITE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setResult(armoredElytraBuilder
|
||||
.newBuilder()
|
||||
.ofElytra(itemStackA)
|
||||
.upgradeToTier(ArmorTier.NETHERITE)
|
||||
.build());
|
||||
.newBuilder()
|
||||
.ofElytra(itemStackA)
|
||||
.upgradeToTier(ArmorTier.NETHERITE)
|
||||
.build());
|
||||
}
|
||||
|
||||
private boolean validInput(@Nullable ItemStack itemStackA, @Nullable ItemStack itemStackB)
|
||||
{
|
||||
private boolean validInput(@Nullable ItemStack itemStackA, @Nullable ItemStack itemStackB) {
|
||||
if (itemStackA == null || itemStackB == null ||
|
||||
itemStackA.getType() != Material.ELYTRA ||
|
||||
plugin.getNbtEditor().getArmorTier(itemStackA) != ArmorTier.DIAMOND ||
|
||||
itemStackB.getType() != Material.NETHERITE_INGOT)
|
||||
itemStackA.getType() != Material.ELYTRA ||
|
||||
plugin.getNbtEditor().getArmorTier(itemStackA) != ArmorTier.DIAMOND ||
|
||||
itemStackB.getType() != Material.NETHERITE_INGOT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// For some reason, adding multiple netherite ingots causes the view to not update properly.
|
||||
// The resulting armored elytra is hidden and the red cross indicates the combination is impossible.
|
||||
@ -61,8 +60,7 @@ public class NetheriteUpgradeListener extends SmithingTableListener
|
||||
|
||||
@Override
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onInventoryClick(InventoryClickEvent event)
|
||||
{
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
super.onInventoryClick(event);
|
||||
}
|
||||
}
|
||||
|
@ -14,20 +14,17 @@ import org.bukkit.event.inventory.PrepareSmithingEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.SmithingInventory;
|
||||
|
||||
public class SmithingTableCraftHandler extends SmithingTableListener
|
||||
{
|
||||
public class SmithingTableCraftHandler extends SmithingTableListener {
|
||||
public SmithingTableCraftHandler(final ArmoredElytra plugin, NBTEditor nbtEditor,
|
||||
DurabilityManager durabilityManager, ConfigLoader config)
|
||||
{
|
||||
DurabilityManager durabilityManager, ConfigLoader config) {
|
||||
super(plugin, true, nbtEditor, durabilityManager, config);
|
||||
// Register the anvil handler with creation disabled so AEs can still be repaired and stuff.
|
||||
Bukkit.getPluginManager()
|
||||
.registerEvents(new AnvilHandler(plugin, false, nbtEditor, durabilityManager, config), plugin);
|
||||
.registerEvents(new AnvilHandler(plugin, false, nbtEditor, durabilityManager, config), plugin);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSmithingTableUsage(final PrepareSmithingEvent event)
|
||||
{
|
||||
public void onSmithingTableUsage(final PrepareSmithingEvent event) {
|
||||
final SmithingInventory inventory = event.getInventory();
|
||||
final ItemStack[] contents = inventory.getContents();
|
||||
|
||||
@ -35,28 +32,29 @@ public class SmithingTableCraftHandler extends SmithingTableListener
|
||||
final ItemStack itemStackB = contents[1];
|
||||
|
||||
final ArmorTier newArmorTier = getNewArmorTier(itemStackA, itemStackB);
|
||||
if (newArmorTier == ArmorTier.NONE)
|
||||
if (newArmorTier == ArmorTier.NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!plugin.playerHasCraftPerm(event.getView().getPlayer(), newArmorTier))
|
||||
if (!plugin.playerHasCraftPerm(event.getView().getPlayer(), newArmorTier)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setResult(armoredElytraBuilder.combine(itemStackA, itemStackB, newArmorTier, null));
|
||||
}
|
||||
|
||||
protected ArmorTier getNewArmorTier(ItemStack itemStackA, ItemStack itemStackB)
|
||||
{
|
||||
protected ArmorTier getNewArmorTier(ItemStack itemStackA, ItemStack itemStackB) {
|
||||
if (itemStackA == null || itemStackB == null ||
|
||||
itemStackA.getType() != Material.ELYTRA || !Util.isChestPlate(itemStackB))
|
||||
itemStackA.getType() != Material.ELYTRA || !Util.isChestPlate(itemStackB)) {
|
||||
return ArmorTier.NONE;
|
||||
}
|
||||
|
||||
return Util.armorToTier(itemStackB.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onInventoryClick(InventoryClickEvent event)
|
||||
{
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
super.onInventoryClick(event);
|
||||
}
|
||||
}
|
||||
|
@ -15,24 +15,23 @@ import org.bukkit.inventory.SmithingInventory;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
abstract class SmithingTableListener extends ArmoredElytraHandler implements Listener
|
||||
{
|
||||
abstract class SmithingTableListener extends ArmoredElytraHandler implements Listener {
|
||||
protected SmithingTableListener(ArmoredElytra plugin, boolean creationEnabled,
|
||||
NBTEditor nbtEditor, DurabilityManager durabilityManager, ConfigLoader config)
|
||||
{
|
||||
NBTEditor nbtEditor, DurabilityManager durabilityManager, ConfigLoader config) {
|
||||
super(plugin, creationEnabled, nbtEditor, durabilityManager, config);
|
||||
}
|
||||
|
||||
protected void onInventoryClick(InventoryClickEvent event)
|
||||
{
|
||||
if (!isAESmithingTableEvent(event))
|
||||
protected void onInventoryClick(InventoryClickEvent event) {
|
||||
if (!isAESmithingTableEvent(event)) {
|
||||
return;
|
||||
}
|
||||
final SmithingInventory smithingInventory = (SmithingInventory) event.getInventory();
|
||||
final ItemStack result = smithingInventory.getItem(2);
|
||||
|
||||
// This cast may look unchecked, but it was checked by isSmithingTableEvent already.
|
||||
if (!giveItemToPlayer((Player) event.getWhoClicked(), result, event.isShiftClick()))
|
||||
if (!giveItemToPlayer((Player) event.getWhoClicked(), result, event.isShiftClick())) {
|
||||
return;
|
||||
}
|
||||
smithingInventory.clear();
|
||||
}
|
||||
|
||||
@ -43,42 +42,39 @@ abstract class SmithingTableListener extends ArmoredElytraHandler implements Lis
|
||||
* @param event The {@link InventoryClickEvent} which may be of use to us.
|
||||
* @return True if this plugin can process this event further.
|
||||
*/
|
||||
protected boolean isAESmithingTableEvent(final InventoryClickEvent event)
|
||||
{
|
||||
if (event.getRawSlot() != 2)
|
||||
protected boolean isAESmithingTableEvent(final InventoryClickEvent event) {
|
||||
if (event.getRawSlot() != 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the event was a player who interacted with a smithing table.
|
||||
final Player player = (Player) event.getWhoClicked();
|
||||
if (event.getView().getType() != InventoryType.SMITHING)
|
||||
if (event.getView().getType() != InventoryType.SMITHING) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SmithingInventory smithingInventory;
|
||||
// Try to cast inventory being used in the event to a smithing inventory.
|
||||
// This will throw a ClassCastException when a CraftInventoryCustom is used.
|
||||
try
|
||||
{
|
||||
try {
|
||||
smithingInventory = (SmithingInventory) event.getInventory();
|
||||
}
|
||||
catch (ClassCastException exception)
|
||||
{
|
||||
} catch (ClassCastException exception) {
|
||||
// Print warning to console and exit onInventoryClick event (no support for
|
||||
// custom inventories as they are usually used for GUI's).
|
||||
plugin.debugMsg(Level.WARNING, "Could not cast inventory to SmithingInventory for player " +
|
||||
player.getName() + "! Armored Elytras cannot be crafted!");
|
||||
player.getName() + "! Armored Elytras cannot be crafted!");
|
||||
exception.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (smithingInventory.getItem(0) == null ||
|
||||
smithingInventory.getItem(1) == null ||
|
||||
smithingInventory.getItem(2) == null)
|
||||
smithingInventory.getItem(1) == null ||
|
||||
smithingInventory.getItem(2) == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ItemStack result = smithingInventory.getItem(2);
|
||||
if (result == null || result.getType() != Material.ELYTRA ||
|
||||
nbtEditor.getArmorTier(result) == ArmorTier.NONE)
|
||||
return false;
|
||||
return true;
|
||||
return result != null && result.getType() == Material.ELYTRA &&
|
||||
nbtEditor.getArmorTier(result) != ArmorTier.NONE;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryOpenEvent;
|
||||
@ -15,24 +14,20 @@ import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
public class Uninstaller implements Listener
|
||||
{
|
||||
public class Uninstaller implements Listener {
|
||||
private final ArmoredElytra plugin;
|
||||
private final NBTEditor nbtEditor;
|
||||
|
||||
public Uninstaller(ArmoredElytra plugin, NBTEditor nbtEditor)
|
||||
{
|
||||
public Uninstaller(ArmoredElytra plugin, NBTEditor nbtEditor) {
|
||||
this.plugin = plugin;
|
||||
this.nbtEditor = nbtEditor;
|
||||
}
|
||||
|
||||
public int removeArmoredElytras(Inventory inv)
|
||||
{
|
||||
public int removeArmoredElytras(Inventory inv) {
|
||||
int count = 0;
|
||||
for (ItemStack is : inv)
|
||||
if (is != null && is.getType() == Material.ELYTRA &&
|
||||
nbtEditor.getArmorTier(is) != ArmorTier.NONE)
|
||||
{
|
||||
nbtEditor.getArmorTier(is) != ArmorTier.NONE) {
|
||||
inv.remove(is);
|
||||
++count;
|
||||
}
|
||||
@ -40,38 +35,36 @@ public class Uninstaller implements Listener
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onChestOpen(InventoryOpenEvent event)
|
||||
{
|
||||
public void onChestOpen(InventoryOpenEvent event) {
|
||||
if (event.getInventory().getType().equals(InventoryType.CHEST))
|
||||
// Slight delay so the inventory has time to get loaded.
|
||||
new BukkitRunnable()
|
||||
{
|
||||
// Slight delay so the inventory has time to get loaded.
|
||||
{
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
public void run() {
|
||||
Inventory inv = event.getInventory();
|
||||
int removed = removeArmoredElytras(inv);
|
||||
if (removed != 0)
|
||||
plugin.messagePlayer((Player) (event.getPlayer()), ChatColor.RED,
|
||||
"Removed " + removed + " armored elytras from your chest!");
|
||||
if (removed != 0) {
|
||||
plugin.messagePlayer(event.getPlayer(), ChatColor.RED,
|
||||
"Removed " + removed + " armored elytras from your chest!");
|
||||
}
|
||||
}
|
||||
}.runTaskLater(plugin, 20);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerLogin(PlayerLoginEvent event)
|
||||
{
|
||||
public void onPlayerLogin(PlayerLoginEvent event) {
|
||||
// Slight delay so the inventory has time to get loaded.
|
||||
new BukkitRunnable()
|
||||
{
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
public void run() {
|
||||
Inventory inv = event.getPlayer().getInventory();
|
||||
int removed = removeArmoredElytras(inv);
|
||||
if (removed != 0)
|
||||
if (removed != 0) {
|
||||
plugin.messagePlayer(event.getPlayer(), ChatColor.RED,
|
||||
"Removed " + removed + " armored elytras from your inventory!");
|
||||
"Removed " + removed + " armored elytras from your inventory!");
|
||||
}
|
||||
}
|
||||
}.runTaskLater(plugin, 20);
|
||||
}
|
||||
|
@ -11,8 +11,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
* @author Arnah
|
||||
* @since Jul 30, 2015
|
||||
*/
|
||||
public final class ArmorEquipEvent extends PlayerEvent implements Cancellable
|
||||
{
|
||||
public final class ArmorEquipEvent extends PlayerEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancel = false;
|
||||
private final EquipMethod equipType;
|
||||
@ -28,8 +27,7 @@ public final class ArmorEquipEvent extends PlayerEvent implements Cancellable
|
||||
* @param newArmorPiece The ItemStack of the armor added.
|
||||
*/
|
||||
public ArmorEquipEvent(final Player player, final EquipMethod equipType, final ArmorType type,
|
||||
final ItemStack oldArmorPiece, final ItemStack newArmorPiece)
|
||||
{
|
||||
final ItemStack oldArmorPiece, final ItemStack newArmorPiece) {
|
||||
super(player);
|
||||
this.equipType = equipType;
|
||||
this.type = type;
|
||||
@ -42,8 +40,7 @@ public final class ArmorEquipEvent extends PlayerEvent implements Cancellable
|
||||
*
|
||||
* @return A list of handlers handling this event.
|
||||
*/
|
||||
public static HandlerList getHandlerList()
|
||||
{
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@ -53,8 +50,7 @@ public final class ArmorEquipEvent extends PlayerEvent implements Cancellable
|
||||
* @return A list of handlers handling this event.
|
||||
*/
|
||||
@Override
|
||||
public final HandlerList getHandlers()
|
||||
{
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@ -64,8 +60,7 @@ public final class ArmorEquipEvent extends PlayerEvent implements Cancellable
|
||||
* @param cancel If this event should be cancelled.
|
||||
*/
|
||||
@Override
|
||||
public final void setCancelled(final boolean cancel)
|
||||
{
|
||||
public void setCancelled(final boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
@ -75,52 +70,44 @@ public final class ArmorEquipEvent extends PlayerEvent implements Cancellable
|
||||
* @return If this event is cancelled
|
||||
*/
|
||||
@Override
|
||||
public final boolean isCancelled()
|
||||
{
|
||||
public boolean isCancelled() {
|
||||
return cancel;
|
||||
}
|
||||
|
||||
public final ArmorType getType()
|
||||
{
|
||||
public ArmorType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last equipped armor piece, could be a piece of armor, {@link Material#Air}, or null.
|
||||
*/
|
||||
public final ItemStack getOldArmorPiece()
|
||||
{
|
||||
public ItemStack getOldArmorPiece() {
|
||||
return oldArmorPiece;
|
||||
}
|
||||
|
||||
public final void setOldArmorPiece(final ItemStack oldArmorPiece)
|
||||
{
|
||||
public void setOldArmorPiece(final ItemStack oldArmorPiece) {
|
||||
this.oldArmorPiece = oldArmorPiece;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the newly equipped armor, could be a piece of armor, {@link Material#Air}, or null.
|
||||
*/
|
||||
public final ItemStack getNewArmorPiece()
|
||||
{
|
||||
public ItemStack getNewArmorPiece() {
|
||||
return newArmorPiece;
|
||||
}
|
||||
|
||||
public final void setNewArmorPiece(final ItemStack newArmorPiece)
|
||||
{
|
||||
public void setNewArmorPiece(final ItemStack newArmorPiece) {
|
||||
this.newArmorPiece = newArmorPiece;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the method used to either equip or unequip an armor piece.
|
||||
*/
|
||||
public EquipMethod getMethod()
|
||||
{
|
||||
public EquipMethod getMethod() {
|
||||
return equipType;
|
||||
}
|
||||
|
||||
public enum EquipMethod
|
||||
{
|
||||
public enum EquipMethod {
|
||||
/**
|
||||
* When you shift click an armor piece to equip or unequip
|
||||
*/
|
||||
@ -154,6 +141,5 @@ public final class ArmorEquipEvent extends PlayerEvent implements Cancellable
|
||||
* When you die causing all armor to unequip
|
||||
*/
|
||||
DEATH,
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@ -25,85 +25,77 @@ import java.util.List;
|
||||
* @author Arnah
|
||||
* @since Jul 30, 2015
|
||||
*/
|
||||
public class ArmorListener implements Listener
|
||||
{
|
||||
public class ArmorListener implements Listener {
|
||||
private final List<String> blockedMaterials;
|
||||
|
||||
public ArmorListener(List<String> blockedMaterials)
|
||||
{
|
||||
public ArmorListener(List<String> blockedMaterials) {
|
||||
this.blockedMaterials = blockedMaterials;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public final void inventoryClick(final InventoryClickEvent e)
|
||||
{
|
||||
public final void inventoryClick(final InventoryClickEvent e) {
|
||||
boolean shift = false, numberkey = false;
|
||||
if (e.isCancelled())
|
||||
if (e.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
if (e.getAction() == InventoryAction.NOTHING)
|
||||
// Why does this get called if nothing happens??
|
||||
// Why does this get called if nothing happens??
|
||||
{
|
||||
return;
|
||||
if (e.getClick().equals(ClickType.SHIFT_LEFT) || e.getClick().equals(ClickType.SHIFT_RIGHT))
|
||||
}
|
||||
if (e.getClick().equals(ClickType.SHIFT_LEFT) || e.getClick().equals(ClickType.SHIFT_RIGHT)) {
|
||||
shift = true;
|
||||
if (e.getClick().equals(ClickType.NUMBER_KEY))
|
||||
}
|
||||
if (e.getClick().equals(ClickType.NUMBER_KEY)) {
|
||||
numberkey = true;
|
||||
}
|
||||
if (e.getSlotType() != SlotType.ARMOR && e.getSlotType() != SlotType.QUICKBAR &&
|
||||
e.getSlotType() != SlotType.CONTAINER)
|
||||
e.getSlotType() != SlotType.CONTAINER) {
|
||||
return;
|
||||
if (e.getClickedInventory() != null && !e.getClickedInventory().getType().equals(InventoryType.PLAYER))
|
||||
}
|
||||
if (e.getClickedInventory() != null && !e.getClickedInventory().getType().equals(InventoryType.PLAYER)) {
|
||||
return;
|
||||
}
|
||||
if (!e.getInventory().getType().equals(InventoryType.CRAFTING) &&
|
||||
!e.getInventory().getType().equals(InventoryType.PLAYER))
|
||||
!e.getInventory().getType().equals(InventoryType.PLAYER)) {
|
||||
return;
|
||||
if (!(e.getWhoClicked() instanceof Player))
|
||||
}
|
||||
if (!(e.getWhoClicked() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
ArmorType newArmorType = ArmorType.matchType(shift ? e.getCurrentItem() : e.getCursor());
|
||||
if (!shift && newArmorType != null && e.getRawSlot() != newArmorType.getSlot())
|
||||
// Used for drag and drop checking to make sure you aren't trying to place a
|
||||
// helmet in the boots slot.
|
||||
return;
|
||||
if (shift)
|
||||
// Used for drag and drop checking to make sure you aren't trying to place a
|
||||
// helmet in the boots slot.
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (shift) {
|
||||
newArmorType = ArmorType.matchType(e.getCurrentItem());
|
||||
if (newArmorType != null)
|
||||
{
|
||||
boolean equipping = true;
|
||||
if (e.getRawSlot() == newArmorType.getSlot())
|
||||
equipping = false;
|
||||
if (newArmorType != null) {
|
||||
boolean equipping = e.getRawSlot() != newArmorType.getSlot();
|
||||
if (newArmorType.equals(ArmorType.HELMET) &&
|
||||
(equipping ? isAirOrNull(e.getWhoClicked().getInventory().getHelmet()) :
|
||||
!isAirOrNull(e.getWhoClicked().getInventory().getHelmet())) ||
|
||||
newArmorType.equals(ArmorType.CHESTPLATE) && (equipping ?
|
||||
isAirOrNull(e.getWhoClicked().getInventory()
|
||||
.getChestplate()) :
|
||||
!isAirOrNull(e.getWhoClicked().getInventory()
|
||||
.getChestplate())) ||
|
||||
newArmorType.equals(ArmorType.LEGGINGS) && (equipping ?
|
||||
isAirOrNull(
|
||||
e.getWhoClicked().getInventory().getLeggings()) :
|
||||
!isAirOrNull(
|
||||
e.getWhoClicked().getInventory().getLeggings())) ||
|
||||
newArmorType.equals(ArmorType.BOOTS) && (equipping ?
|
||||
isAirOrNull(e.getWhoClicked().getInventory().getBoots()) :
|
||||
!isAirOrNull(e.getWhoClicked().getInventory().getBoots())))
|
||||
{
|
||||
(equipping == isAirOrNull(e.getWhoClicked().getInventory().getHelmet())) ||
|
||||
newArmorType.equals(ArmorType.CHESTPLATE) && (equipping == isAirOrNull(e.getWhoClicked().getInventory()
|
||||
.getChestplate())) ||
|
||||
newArmorType.equals(ArmorType.LEGGINGS) && (equipping == isAirOrNull(
|
||||
e.getWhoClicked().getInventory().getLeggings())) ||
|
||||
newArmorType.equals(ArmorType.BOOTS) && (equipping == isAirOrNull(e.getWhoClicked().getInventory().getBoots()))) {
|
||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(),
|
||||
EquipMethod.SHIFT_CLICK, newArmorType,
|
||||
equipping ? null : e.getCurrentItem(),
|
||||
equipping ? e.getCurrentItem() : null);
|
||||
EquipMethod.SHIFT_CLICK, newArmorType,
|
||||
equipping ? null : e.getCurrentItem(),
|
||||
equipping ? e.getCurrentItem() : null);
|
||||
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
|
||||
if (armorEquipEvent.isCancelled())
|
||||
if (armorEquipEvent.isCancelled()) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ItemStack newArmorPiece = e.getCursor();
|
||||
ItemStack oldArmorPiece = e.getCurrentItem();
|
||||
if (numberkey)
|
||||
if (e.getClickedInventory().getType().equals(InventoryType.PLAYER))
|
||||
{
|
||||
if (numberkey) {
|
||||
if (e.getClickedInventory().getType().equals(InventoryType.PLAYER)) {
|
||||
// Prevents shit in the 2by2 crafting
|
||||
// e.getClickedInventory() == The players inventory
|
||||
// e.getHotBarButton() == key people are pressing to equip or unequip the item
|
||||
@ -112,72 +104,70 @@ public class ArmorListener implements Listener
|
||||
// e.getSlot() == Armor slot, can't use e.getRawSlot() as that gives a hotbar
|
||||
// slot ;-;
|
||||
ItemStack hotbarItem = e.getClickedInventory().getItem(e.getHotbarButton());
|
||||
if (!isAirOrNull(hotbarItem))
|
||||
{
|
||||
if (!isAirOrNull(hotbarItem)) {
|
||||
// Equipping
|
||||
newArmorType = ArmorType.matchType(hotbarItem);
|
||||
newArmorPiece = hotbarItem;
|
||||
oldArmorPiece = e.getClickedInventory().getItem(e.getSlot());
|
||||
}
|
||||
else
|
||||
// Unequipping
|
||||
} else
|
||||
// Unequipping
|
||||
{
|
||||
newArmorType = ArmorType
|
||||
.matchType(!isAirOrNull(e.getCurrentItem()) ? e.getCurrentItem() : e.getCursor());
|
||||
}
|
||||
else
|
||||
{
|
||||
.matchType(!isAirOrNull(e.getCurrentItem()) ? e.getCurrentItem() : e.getCursor());
|
||||
}
|
||||
} else {
|
||||
if (isAirOrNull(e.getCursor()) && !isAirOrNull(e.getCurrentItem()))
|
||||
// unequip with no new item going into the slot.
|
||||
// unequip with no new item going into the slot.
|
||||
{
|
||||
newArmorType = ArmorType.matchType(e.getCurrentItem());
|
||||
}
|
||||
}
|
||||
if (newArmorType != null && e.getRawSlot() == newArmorType.getSlot())
|
||||
{
|
||||
}
|
||||
if (newArmorType != null && e.getRawSlot() == newArmorType.getSlot()) {
|
||||
EquipMethod method = EquipMethod.PICK_DROP;
|
||||
if (e.getAction().equals(InventoryAction.HOTBAR_SWAP) || numberkey)
|
||||
if (e.getAction().equals(InventoryAction.HOTBAR_SWAP) || numberkey) {
|
||||
method = EquipMethod.HOTBAR_SWAP;
|
||||
}
|
||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(), method, newArmorType,
|
||||
oldArmorPiece, newArmorPiece);
|
||||
oldArmorPiece, newArmorPiece);
|
||||
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
|
||||
if (armorEquipEvent.isCancelled())
|
||||
if (armorEquipEvent.isCancelled()) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void playerInteractEvent(PlayerInteractEvent e)
|
||||
{
|
||||
if (e.getAction() == Action.PHYSICAL)
|
||||
public void playerInteractEvent(PlayerInteractEvent e) {
|
||||
if (e.getAction() == Action.PHYSICAL) {
|
||||
return;
|
||||
if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK)
|
||||
{
|
||||
}
|
||||
if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||
final Player player = e.getPlayer();
|
||||
if (e.getClickedBlock() != null && e.getAction() == Action.RIGHT_CLICK_BLOCK)
|
||||
{
|
||||
if (e.getClickedBlock() != null && e.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||
// Having both of these checks is useless, might as well do it though.
|
||||
// Some blocks have actions when you right click them which stops the client
|
||||
// from equipping the armor in hand.
|
||||
Material mat = e.getClickedBlock().getType();
|
||||
for (String s : blockedMaterials)
|
||||
if (mat.name().equalsIgnoreCase(s))
|
||||
if (mat.name().equalsIgnoreCase(s)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
ArmorType newArmorType = ArmorType.matchType(e.getItem());
|
||||
if (newArmorType != null)
|
||||
{
|
||||
if (newArmorType != null) {
|
||||
if (newArmorType.equals(ArmorType.HELMET) && isAirOrNull(e.getPlayer().getInventory().getHelmet()) ||
|
||||
newArmorType
|
||||
.equals(ArmorType.CHESTPLATE) && isAirOrNull(e.getPlayer().getInventory().getChestplate()) ||
|
||||
newArmorType
|
||||
.equals(ArmorType.LEGGINGS) && isAirOrNull(e.getPlayer().getInventory().getLeggings()) ||
|
||||
newArmorType.equals(ArmorType.BOOTS) && isAirOrNull(e.getPlayer().getInventory().getBoots()))
|
||||
{
|
||||
newArmorType
|
||||
.equals(ArmorType.CHESTPLATE) && isAirOrNull(e.getPlayer().getInventory().getChestplate()) ||
|
||||
newArmorType
|
||||
.equals(ArmorType.LEGGINGS) && isAirOrNull(e.getPlayer().getInventory().getLeggings()) ||
|
||||
newArmorType.equals(ArmorType.BOOTS) && isAirOrNull(e.getPlayer().getInventory().getBoots())) {
|
||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(e.getPlayer(), EquipMethod.HOTBAR,
|
||||
ArmorType.matchType(e.getItem()), null,
|
||||
e.getItem());
|
||||
ArmorType.matchType(e.getItem()), null,
|
||||
e.getItem());
|
||||
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
|
||||
if (armorEquipEvent.isCancelled())
|
||||
{
|
||||
if (armorEquipEvent.isCancelled()) {
|
||||
e.setCancelled(true);
|
||||
player.updateInventory();
|
||||
}
|
||||
@ -187,23 +177,22 @@ public class ArmorListener implements Listener
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void inventoryDrag(InventoryDragEvent event)
|
||||
{
|
||||
public void inventoryDrag(InventoryDragEvent event) {
|
||||
// getType() seems to always be even.
|
||||
// Old Cursor gives the item you are equipping
|
||||
// Raw slot is the ArmorType slot
|
||||
// Can't replace armor using this method making getCursor() useless.
|
||||
ArmorType type = ArmorType.matchType(event.getOldCursor());
|
||||
if (event.getRawSlots().isEmpty())
|
||||
// Idk if this will ever happen
|
||||
return;
|
||||
if (type != null && type.getSlot() == event.getRawSlots().stream().findFirst().orElse(0))
|
||||
// Idk if this will ever happen
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (type != null && type.getSlot() == event.getRawSlots().stream().findFirst().orElse(0)) {
|
||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) event.getWhoClicked(), EquipMethod.DRAG,
|
||||
type, null, event.getOldCursor());
|
||||
type, null, event.getOldCursor());
|
||||
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
|
||||
if (armorEquipEvent.isCancelled())
|
||||
{
|
||||
if (armorEquipEvent.isCancelled()) {
|
||||
event.setResult(Result.DENY);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
@ -211,41 +200,37 @@ public class ArmorListener implements Listener
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void itemBreakEvent(PlayerItemBreakEvent e)
|
||||
{
|
||||
public void itemBreakEvent(PlayerItemBreakEvent e) {
|
||||
ArmorType type = ArmorType.matchType(e.getBrokenItem());
|
||||
if (type != null)
|
||||
{
|
||||
if (type != null) {
|
||||
Player p = e.getPlayer();
|
||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, EquipMethod.BROKE, type, e.getBrokenItem(), null);
|
||||
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
|
||||
if (armorEquipEvent.isCancelled())
|
||||
{
|
||||
if (armorEquipEvent.isCancelled()) {
|
||||
ItemStack i = e.getBrokenItem().clone();
|
||||
i.setAmount(1);
|
||||
i.setDurability((short) (i.getDurability() - 1));
|
||||
if (type.equals(ArmorType.HELMET))
|
||||
if (type.equals(ArmorType.HELMET)) {
|
||||
p.getInventory().setHelmet(i);
|
||||
else if (type.equals(ArmorType.CHESTPLATE))
|
||||
} else if (type.equals(ArmorType.CHESTPLATE)) {
|
||||
p.getInventory().setChestplate(i);
|
||||
else if (type.equals(ArmorType.LEGGINGS))
|
||||
} else if (type.equals(ArmorType.LEGGINGS)) {
|
||||
p.getInventory().setLeggings(i);
|
||||
else if (type.equals(ArmorType.BOOTS))
|
||||
} else if (type.equals(ArmorType.BOOTS)) {
|
||||
p.getInventory().setBoots(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void playerDeathEvent(PlayerDeathEvent e)
|
||||
{
|
||||
public void playerDeathEvent(PlayerDeathEvent e) {
|
||||
Player p = e.getEntity();
|
||||
for (ItemStack oldArmor : p.getInventory().getArmorContents())
|
||||
if (!isAirOrNull(oldArmor))
|
||||
{
|
||||
if (!isAirOrNull(oldArmor)) {
|
||||
ArmorType type = ArmorType.matchType(oldArmor);
|
||||
Bukkit.getServer().getPluginManager().callEvent(new ArmorEquipEvent(p, EquipMethod.DEATH,
|
||||
type, oldArmor, null));
|
||||
type, oldArmor, null));
|
||||
// No way to cancel a death event.
|
||||
}
|
||||
}
|
||||
@ -253,8 +238,7 @@ public class ArmorListener implements Listener
|
||||
/**
|
||||
* A utility method to support versions that use null or air ItemStacks.
|
||||
*/
|
||||
private boolean isAirOrNull(ItemStack item)
|
||||
{
|
||||
private boolean isAirOrNull(ItemStack item) {
|
||||
return item == null || item.getType().equals(Material.AIR);
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
* @author Arnah
|
||||
* @since Jul 30, 2015
|
||||
*/
|
||||
public enum ArmorType
|
||||
{
|
||||
public enum ArmorType {
|
||||
HELMET(5),
|
||||
CHESTPLATE(6),
|
||||
LEGGINGS(7),
|
||||
@ -16,8 +15,7 @@ public enum ArmorType
|
||||
|
||||
private final int slot;
|
||||
|
||||
ArmorType(int slot)
|
||||
{
|
||||
ArmorType(int slot) {
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
@ -27,27 +25,28 @@ public enum ArmorType
|
||||
* @param itemStack The ItemStack to parse the type of.
|
||||
* @return The parsed ArmorType. (null if none were found.)
|
||||
*/
|
||||
public static final ArmorType matchType(final ItemStack itemStack)
|
||||
{
|
||||
if (itemStack == null || itemStack.getType().equals(Material.AIR))
|
||||
public static ArmorType matchType(final ItemStack itemStack) {
|
||||
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
|
||||
return null;
|
||||
if (itemStack.getType().equals(Material.ELYTRA))
|
||||
}
|
||||
if (itemStack.getType().equals(Material.ELYTRA)) {
|
||||
return CHESTPLATE;
|
||||
}
|
||||
String type = itemStack.getType().name();
|
||||
if (type.endsWith("_HELMET") || type.endsWith("_SKULL"))
|
||||
if (type.endsWith("_HELMET") || type.endsWith("_SKULL")) {
|
||||
return HELMET;
|
||||
else if (type.endsWith("_CHESTPLATE"))
|
||||
} else if (type.endsWith("_CHESTPLATE")) {
|
||||
return CHESTPLATE;
|
||||
else if (type.endsWith("_LEGGINGS"))
|
||||
} else if (type.endsWith("_LEGGINGS")) {
|
||||
return LEGGINGS;
|
||||
else if (type.endsWith("_BOOTS"))
|
||||
} else if (type.endsWith("_BOOTS")) {
|
||||
return BOOTS;
|
||||
else
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getSlot()
|
||||
{
|
||||
public int getSlot() {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
|
@ -10,21 +10,19 @@ import org.bukkit.event.block.BlockDispenseArmorEvent;
|
||||
* @author Arnah
|
||||
* @since Feb 08, 2019
|
||||
*/
|
||||
public class DispenserArmorListener implements Listener
|
||||
{
|
||||
public class DispenserArmorListener implements Listener {
|
||||
@EventHandler
|
||||
public void dispenseArmorEvent(BlockDispenseArmorEvent event)
|
||||
{
|
||||
public void dispenseArmorEvent(BlockDispenseArmorEvent event) {
|
||||
ArmorType type = ArmorType.matchType(event.getItem());
|
||||
if (type != null)
|
||||
if (event.getTargetEntity() instanceof Player)
|
||||
{
|
||||
Player p = (Player) event.getTargetEntity();
|
||||
if (type != null) {
|
||||
if (event.getTargetEntity() instanceof Player p) {
|
||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, ArmorEquipEvent.EquipMethod.DISPENSER, type,
|
||||
null, event.getItem());
|
||||
null, event.getItem());
|
||||
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
|
||||
if (armorEquipEvent.isCancelled())
|
||||
if (armorEquipEvent.isCancelled()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,17 +14,15 @@ import org.bukkit.inventory.meta.LeatherArmorMeta;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"unused", "UnusedReturnValue", "ClassCanBeRecord"})
|
||||
public class ArmoredElytraBuilder
|
||||
{
|
||||
@SuppressWarnings({"unused", "UnusedReturnValue"})
|
||||
public class ArmoredElytraBuilder {
|
||||
private final NBTEditor nbtEditor;
|
||||
private final DurabilityManager durabilityManager;
|
||||
private final ConfigLoader config;
|
||||
private final ArmoredElytra plugin;
|
||||
|
||||
public ArmoredElytraBuilder(NBTEditor nbtEditor, DurabilityManager durabilityManager,
|
||||
ConfigLoader config, ArmoredElytra plugin)
|
||||
{
|
||||
ConfigLoader config, ArmoredElytra plugin) {
|
||||
|
||||
this.nbtEditor = nbtEditor;
|
||||
this.durabilityManager = durabilityManager;
|
||||
@ -37,8 +35,7 @@ public class ArmoredElytraBuilder
|
||||
*
|
||||
* @return The first step of the new builder.
|
||||
*/
|
||||
public IStep0 newBuilder()
|
||||
{
|
||||
public IStep0 newBuilder() {
|
||||
return new Builder(nbtEditor, durabilityManager, config, plugin);
|
||||
}
|
||||
|
||||
@ -52,8 +49,7 @@ public class ArmoredElytraBuilder
|
||||
* ArmoredElytra#getArmoredElytraName(ArmorTier)} is used to set the name.
|
||||
* @return The new armored elytra.
|
||||
*/
|
||||
public @Nullable ItemStack repair(ItemStack armoredElytra, ItemStack repairItems, @Nullable String name)
|
||||
{
|
||||
public @Nullable ItemStack repair(ItemStack armoredElytra, ItemStack repairItems, @Nullable String name) {
|
||||
return newBuilder().ofElytra(armoredElytra).repair(repairItems.getAmount()).withName(name).build();
|
||||
}
|
||||
|
||||
@ -66,11 +62,11 @@ public class ArmoredElytraBuilder
|
||||
* ArmoredElytra#getArmoredElytraName(ArmorTier)} is used to set the name.
|
||||
* @return The new armored elytra.
|
||||
*/
|
||||
public @Nullable ItemStack enchant(ItemStack armoredElytra, ItemStack sourceItem, @Nullable String name)
|
||||
{
|
||||
public @Nullable ItemStack enchant(ItemStack armoredElytra, ItemStack sourceItem, @Nullable String name) {
|
||||
final EnchantmentContainer enchantments = EnchantmentContainer.getEnchantmentsOf(sourceItem, plugin);
|
||||
if (enchantments.isEmpty())
|
||||
if (enchantments.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return newBuilder().ofElytra(armoredElytra).addEnchantments(enchantments).withName(name).build();
|
||||
}
|
||||
|
||||
@ -86,16 +82,14 @@ public class ArmoredElytraBuilder
|
||||
* ArmoredElytra#getArmoredElytraName(ArmorTier)} is used to set the name.
|
||||
* @return The new armored elytra.
|
||||
*/
|
||||
public ItemStack combine(ItemStack elytra, ItemStack combiner, ArmorTier armorTier, @Nullable String name)
|
||||
{
|
||||
public ItemStack combine(ItemStack elytra, ItemStack combiner, ArmorTier armorTier, @Nullable String name) {
|
||||
return newBuilder().ofElytra(elytra).combineWith(combiner, armorTier).withName(name).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #combine(ItemStack, ItemStack, ArmorTier, String)} for unknown armor tiers.
|
||||
*/
|
||||
public ItemStack combine(ItemStack elytra, ItemStack combiner, @Nullable String name)
|
||||
{
|
||||
public ItemStack combine(ItemStack elytra, ItemStack combiner, @Nullable String name) {
|
||||
return newBuilder().ofElytra(elytra).combineWith(combiner).withName(name).build();
|
||||
}
|
||||
|
||||
@ -105,16 +99,14 @@ public class ArmoredElytraBuilder
|
||||
* @param armorTier The tier of the new armored elytra.
|
||||
* @return The new armored elytra.
|
||||
*/
|
||||
public ItemStack newArmoredElytra(ArmorTier armorTier)
|
||||
{
|
||||
public ItemStack newArmoredElytra(ArmorTier armorTier) {
|
||||
return newBuilder().newItem(armorTier).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the third and last step of the armored elytra build process.
|
||||
*/
|
||||
public interface IStep2
|
||||
{
|
||||
public interface IStep2 {
|
||||
/**
|
||||
* Specifies the new name of the armored elytra.
|
||||
*
|
||||
@ -163,8 +155,7 @@ public class ArmoredElytraBuilder
|
||||
/**
|
||||
* Represents the second and last step of the armored elytra build process.
|
||||
*/
|
||||
public interface IStep1
|
||||
{
|
||||
public interface IStep1 {
|
||||
/**
|
||||
* Repairs the armored elytra provided as input.
|
||||
*
|
||||
@ -219,8 +210,7 @@ public class ArmoredElytraBuilder
|
||||
/**
|
||||
* Represents the first and last step of the armored elytra build process.
|
||||
*/
|
||||
public interface IStep0
|
||||
{
|
||||
public interface IStep0 {
|
||||
/**
|
||||
* Use an elytra as base item to create the new armored elytra from.
|
||||
*
|
||||
@ -239,8 +229,7 @@ public class ArmoredElytraBuilder
|
||||
IStep2 newItem(ArmorTier armorTier);
|
||||
}
|
||||
|
||||
private static final class Builder implements IStep0, IStep1, IStep2
|
||||
{
|
||||
private static final class Builder implements IStep0, IStep1, IStep2 {
|
||||
private static final Color DEFAULT_LEATHER_COLOR = Bukkit.getServer().getItemFactory().getDefaultLeatherColor();
|
||||
|
||||
private final NBTEditor nbtEditor;
|
||||
@ -293,8 +282,7 @@ public class ArmoredElytraBuilder
|
||||
private @Nullable Boolean isUnbreakable = null;
|
||||
|
||||
private Builder(NBTEditor nbtEditor, DurabilityManager durabilityManager,
|
||||
ConfigLoader config, ArmoredElytra plugin)
|
||||
{
|
||||
ConfigLoader config, ArmoredElytra plugin) {
|
||||
this.nbtEditor = nbtEditor;
|
||||
this.durabilityManager = durabilityManager;
|
||||
this.config = config;
|
||||
@ -302,8 +290,7 @@ public class ArmoredElytraBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack build()
|
||||
{
|
||||
public ItemStack build() {
|
||||
// Get default values if unset.
|
||||
newArmorTier = newArmorTier == null ? currentArmorTier : newArmorTier;
|
||||
name = name == null ? plugin.getArmoredElytraName(newArmorTier) : name;
|
||||
@ -312,7 +299,7 @@ public class ArmoredElytraBuilder
|
||||
isUnbreakable = isUnbreakable == null ? config.unbreakable() : isUnbreakable;
|
||||
|
||||
final ItemStack output = nbtEditor.addArmorNBTTags(newArmoredElytra, newArmorTier,
|
||||
isUnbreakable, name, lore, color);
|
||||
isUnbreakable, name, lore, color);
|
||||
durabilityManager.setDurability(output, durability, newArmorTier);
|
||||
combinedEnchantments.applyEnchantments(output);
|
||||
|
||||
@ -320,100 +307,94 @@ public class ArmoredElytraBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 withName(@Nullable String name)
|
||||
{
|
||||
public IStep2 withName(@Nullable String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 withColor(@Nullable Color color)
|
||||
{
|
||||
public IStep2 withColor(@Nullable Color color) {
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 withLore(@Nullable List<String> lore)
|
||||
{
|
||||
public IStep2 withLore(@Nullable List<String> lore) {
|
||||
this.lore = lore;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 unbreakable(boolean isUnbreakable)
|
||||
{
|
||||
public IStep2 unbreakable(boolean isUnbreakable) {
|
||||
this.isUnbreakable = isUnbreakable;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 repair(int count)
|
||||
{
|
||||
if (currentArmorTier == ArmorTier.NONE)
|
||||
public IStep2 repair(int count) {
|
||||
if (currentArmorTier == ArmorTier.NONE) {
|
||||
throw new IllegalArgumentException("Non-armored elytras cannot be repaired!");
|
||||
}
|
||||
durability = durabilityManager.getRepairedDurability(newArmoredElytra, count, currentArmorTier);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 addEnchantments(EnchantmentContainer enchantmentContainer)
|
||||
{
|
||||
public IStep2 addEnchantments(EnchantmentContainer enchantmentContainer) {
|
||||
combinedEnchantments.merge(enchantmentContainer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 addEnchantments(ItemStack sourceItem)
|
||||
{
|
||||
public IStep2 addEnchantments(ItemStack sourceItem) {
|
||||
return addEnchantments(EnchantmentContainer.getEnchantmentsOf(sourceItem, plugin));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 combineWith(ItemStack item, ArmorTier armorTier)
|
||||
{
|
||||
if (armorTier == ArmorTier.NONE && !Util.isChestPlate(item))
|
||||
public IStep2 combineWith(ItemStack item, ArmorTier armorTier) {
|
||||
if (armorTier == ArmorTier.NONE && !Util.isChestPlate(item)) {
|
||||
throw new IllegalArgumentException("Non-armored elytras can only be combined with chest plates!");
|
||||
}
|
||||
|
||||
newArmorTier = armorTier;
|
||||
if (currentArmorTier == ArmorTier.NONE &&
|
||||
item.getType().equals(Material.ELYTRA) && newArmorTier != ArmorTier.NONE)
|
||||
item.getType().equals(Material.ELYTRA) && newArmorTier != ArmorTier.NONE) {
|
||||
throw new IllegalArgumentException("A regular elytra cannot be combined with an armored one!");
|
||||
}
|
||||
|
||||
withColor(getItemColor(newArmoredElytra, item));
|
||||
|
||||
addEnchantments(item);
|
||||
|
||||
durability = durabilityManager.getCombinedDurability(newArmoredElytra, item,
|
||||
currentArmorTier, newArmorTier);
|
||||
currentArmorTier, newArmorTier);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 combineWith(ItemStack item)
|
||||
{
|
||||
public IStep2 combineWith(ItemStack item) {
|
||||
final ArmorTier armorTier = item.getType().equals(Material.ELYTRA) ?
|
||||
nbtEditor.getArmorTier(item) : Util.armorToTier(item.getType());
|
||||
nbtEditor.getArmorTier(item) : Util.armorToTier(item.getType());
|
||||
return combineWith(item, armorTier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 upgradeToTier(ArmorTier armorTier)
|
||||
{
|
||||
public IStep2 upgradeToTier(ArmorTier armorTier) {
|
||||
newArmorTier = armorTier;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep1 ofElytra(ItemStack elytra)
|
||||
{
|
||||
if (!elytra.getType().equals(Material.ELYTRA))
|
||||
public IStep1 ofElytra(ItemStack elytra) {
|
||||
if (!elytra.getType().equals(Material.ELYTRA)) {
|
||||
throw new IllegalArgumentException("Expected elytra as input, but got: " + elytra);
|
||||
}
|
||||
|
||||
newArmoredElytra = new ItemStack(elytra);
|
||||
|
||||
if (currentArmorTier == null)
|
||||
if (currentArmorTier == null) {
|
||||
currentArmorTier = nbtEditor.getArmorTier(elytra);
|
||||
}
|
||||
|
||||
combinedEnchantments = EnchantmentContainer.getEnchantmentsOf(newArmoredElytra, plugin);
|
||||
|
||||
@ -422,8 +403,7 @@ public class ArmoredElytraBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 newItem(ArmorTier armorTier)
|
||||
{
|
||||
public IStep2 newItem(ArmorTier armorTier) {
|
||||
currentArmorTier = newArmorTier = armorTier;
|
||||
ofElytra(new ItemStack(Material.ELYTRA));
|
||||
return this;
|
||||
@ -438,11 +418,11 @@ public class ArmoredElytraBuilder
|
||||
* @param itemB The second {@link ItemStack} to check.
|
||||
* @return The color of the item, if it has a color, otherwise null.
|
||||
*/
|
||||
private @Nullable Color getItemColor(final ItemStack itemA, final ItemStack itemB)
|
||||
{
|
||||
private @Nullable Color getItemColor(final ItemStack itemA, final ItemStack itemB) {
|
||||
final @Nullable Color colorA = getItemColor(itemA);
|
||||
if (colorA != null && !colorA.equals(DEFAULT_LEATHER_COLOR))
|
||||
if (colorA != null && !colorA.equals(DEFAULT_LEATHER_COLOR)) {
|
||||
return colorA;
|
||||
}
|
||||
|
||||
final @Nullable Color colorB = getItemColor(itemB);
|
||||
return colorB != null ? colorB : colorA;
|
||||
@ -456,13 +436,14 @@ public class ArmoredElytraBuilder
|
||||
* @param itemStack The item to analyze.
|
||||
* @return The color of the item, if available, otherwise null.
|
||||
*/
|
||||
private @Nullable Color getItemColor(final ItemStack itemStack)
|
||||
{
|
||||
if (itemStack.getType() == Material.ELYTRA)
|
||||
private @Nullable Color getItemColor(final ItemStack itemStack) {
|
||||
if (itemStack.getType() == Material.ELYTRA) {
|
||||
return nbtEditor.getColorOfArmoredElytra(itemStack);
|
||||
}
|
||||
|
||||
if (!itemStack.hasItemMeta() || !(itemStack.getItemMeta() instanceof LeatherArmorMeta))
|
||||
if (!itemStack.hasItemMeta() || !(itemStack.getItemMeta() instanceof LeatherArmorMeta)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ((LeatherArmorMeta) itemStack.getItemMeta()).getColor();
|
||||
}
|
||||
|
@ -8,8 +8,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class DurabilityManager
|
||||
{
|
||||
public class DurabilityManager {
|
||||
private static final int ELYTRA_MAX_DURABILITY = Material.ELYTRA.getMaxDurability();
|
||||
|
||||
private final int[] repairAmounts = new int[ArmorTier.values().length];
|
||||
@ -18,8 +17,7 @@ public class DurabilityManager
|
||||
private final NBTEditor nbtEditor;
|
||||
private final ConfigLoader config;
|
||||
|
||||
public DurabilityManager(NBTEditor nbtEditor, ConfigLoader config)
|
||||
{
|
||||
public DurabilityManager(NBTEditor nbtEditor, ConfigLoader config) {
|
||||
this.nbtEditor = nbtEditor;
|
||||
this.config = config;
|
||||
init();
|
||||
@ -40,10 +38,10 @@ public class DurabilityManager
|
||||
* @param targetTier The target tier of the armored elytra.
|
||||
*/
|
||||
public int setCombinedDurability(ItemStack armoredElytraOut, ItemStack armoredElytraIn, ItemStack other,
|
||||
ArmorTier currentTier, ArmorTier targetTier)
|
||||
{
|
||||
if (nbtEditor.isUnbreakable(armoredElytraIn))
|
||||
ArmorTier currentTier, ArmorTier targetTier) {
|
||||
if (nbtEditor.isUnbreakable(armoredElytraIn)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final int combinedDurability = getCombinedDurability(armoredElytraIn, other, currentTier, targetTier);
|
||||
setDurability(armoredElytraOut, combinedDurability, targetTier);
|
||||
@ -61,24 +59,24 @@ public class DurabilityManager
|
||||
* @return The new real durability value of the armored elytra if it were to be combined with the other item.
|
||||
*/
|
||||
public int getCombinedDurability(ItemStack armoredElytra, ItemStack other,
|
||||
ArmorTier currentTier, ArmorTier targetTier)
|
||||
{
|
||||
if (nbtEditor.isUnbreakable(armoredElytra))
|
||||
ArmorTier currentTier, ArmorTier targetTier) {
|
||||
if (nbtEditor.isUnbreakable(armoredElytra)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final ArmorTier otherTier = nbtEditor.getArmorTier(other);
|
||||
|
||||
final int currentMaxDurability = getMaxDurability(currentTier);
|
||||
final int targetMaxDurability = getMaxDurability(targetTier);
|
||||
final int otherMaxDurability = otherTier != ArmorTier.NONE ?
|
||||
getMaxDurability(otherTier) : other.getType().getMaxDurability();
|
||||
getMaxDurability(otherTier) : other.getType().getMaxDurability();
|
||||
final int otherDurability = other.getType().equals(Material.ELYTRA) ?
|
||||
getRealDurability(other, null) : getItemDurability(other);
|
||||
getRealDurability(other, null) : getItemDurability(other);
|
||||
final int currentDurability = getRealDurability(armoredElytra, currentTier);
|
||||
|
||||
final int combinedDurability = targetMaxDurability -
|
||||
(otherMaxDurability - otherDurability) -
|
||||
(currentMaxDurability - currentDurability);
|
||||
(otherMaxDurability - otherDurability) -
|
||||
(currentMaxDurability - currentDurability);
|
||||
|
||||
return Util.between(combinedDurability, 0, targetMaxDurability);
|
||||
}
|
||||
@ -92,10 +90,10 @@ public class DurabilityManager
|
||||
* retrieved from the item itself.
|
||||
* @return The new durability after removing the provided amount.
|
||||
*/
|
||||
public int removeDurability(ItemStack armoredElytra, int durabilityLoss, @Nullable ArmorTier providedTier)
|
||||
{
|
||||
if (nbtEditor.isUnbreakable(armoredElytra))
|
||||
public int removeDurability(ItemStack armoredElytra, int durabilityLoss, @Nullable ArmorTier providedTier) {
|
||||
if (nbtEditor.isUnbreakable(armoredElytra)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final ArmorTier currentTier = providedTier == null ? nbtEditor.getArmorTier(armoredElytra) : providedTier;
|
||||
final int currentDurability = getRealDurability(armoredElytra, currentTier);
|
||||
@ -115,10 +113,10 @@ public class DurabilityManager
|
||||
* from the item itself.
|
||||
* @return The required number of repair items required to fully repair the armored elytra.
|
||||
*/
|
||||
public int getFullRepairItemCount(ItemStack armoredElytra, @Nullable ArmorTier providedTier)
|
||||
{
|
||||
if (nbtEditor.isUnbreakable(armoredElytra))
|
||||
public int getFullRepairItemCount(ItemStack armoredElytra, @Nullable ArmorTier providedTier) {
|
||||
if (nbtEditor.isUnbreakable(armoredElytra)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final ArmorTier currentTier = providedTier == null ? nbtEditor.getArmorTier(armoredElytra) : providedTier;
|
||||
final int repairableDurability = getMaxDurability(currentTier) - getRealDurability(armoredElytra, currentTier);
|
||||
@ -135,10 +133,10 @@ public class DurabilityManager
|
||||
* from the item itself.
|
||||
* @return The real durability value of the armored elytra if it were to be repaired.
|
||||
*/
|
||||
public int getRepairedDurability(ItemStack armoredElytra, int repairCount, @Nullable ArmorTier providedTier)
|
||||
{
|
||||
if (nbtEditor.isUnbreakable(armoredElytra))
|
||||
public int getRepairedDurability(ItemStack armoredElytra, int repairCount, @Nullable ArmorTier providedTier) {
|
||||
if (nbtEditor.isUnbreakable(armoredElytra)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final ArmorTier currentTier = providedTier == null ? nbtEditor.getArmorTier(armoredElytra) : providedTier;
|
||||
final int restoredDurability = repairCount * getRepairAmount(currentTier);
|
||||
@ -156,15 +154,16 @@ public class DurabilityManager
|
||||
* from the item itself.
|
||||
* @return The real durability of the item.
|
||||
*/
|
||||
public int getRealDurability(ItemStack item, @Nullable ArmorTier providedTier)
|
||||
{
|
||||
public int getRealDurability(ItemStack item, @Nullable ArmorTier providedTier) {
|
||||
final ArmorTier currentTier = providedTier == null ? nbtEditor.getArmorTier(item) : providedTier;
|
||||
|
||||
if (currentTier == ArmorTier.NONE)
|
||||
if (currentTier == ArmorTier.NONE) {
|
||||
return getItemDurability(item);
|
||||
}
|
||||
|
||||
if (nbtEditor.isUnbreakable(item))
|
||||
if (nbtEditor.isUnbreakable(item)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final int realDurability = nbtEditor.getRealDurability(item, currentTier);
|
||||
return realDurability == -1 ? upgradeArmoredElytraToDurability(item, currentTier) : realDurability;
|
||||
@ -178,10 +177,10 @@ public class DurabilityManager
|
||||
* @param providedTier The tier of the armored elytra (if this is available). If this is null, it will be retrieved
|
||||
* from the item itself.
|
||||
*/
|
||||
public void setDurability(ItemStack item, int durability, @Nullable ArmorTier providedTier)
|
||||
{
|
||||
if (nbtEditor.isUnbreakable(item))
|
||||
public void setDurability(ItemStack item, int durability, @Nullable ArmorTier providedTier) {
|
||||
if (nbtEditor.isUnbreakable(item)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ArmorTier currentTier = providedTier == null ? nbtEditor.getArmorTier(item) : providedTier;
|
||||
final int oldMaxDurability = getMaxDurability(currentTier);
|
||||
@ -199,14 +198,13 @@ public class DurabilityManager
|
||||
* @param currentTier The current tier of the armored elytra.
|
||||
* @return The real durability of the armored elytra.
|
||||
*/
|
||||
private int upgradeArmoredElytraToDurability(ItemStack armoredElytra, ArmorTier currentTier)
|
||||
{
|
||||
private int upgradeArmoredElytraToDurability(ItemStack armoredElytra, ArmorTier currentTier) {
|
||||
final int maxDurability = getMaxDurability(currentTier);
|
||||
final int rawDurability = getItemDurability(armoredElytra);
|
||||
|
||||
final int realDurability = maxDurability == ELYTRA_MAX_DURABILITY ?
|
||||
rawDurability :
|
||||
getRemappedDurability(rawDurability, ELYTRA_MAX_DURABILITY, maxDurability);
|
||||
rawDurability :
|
||||
getRemappedDurability(rawDurability, ELYTRA_MAX_DURABILITY, maxDurability);
|
||||
|
||||
nbtEditor.updateDurability(armoredElytra, realDurability, rawDurability);
|
||||
return realDurability;
|
||||
@ -219,10 +217,10 @@ public class DurabilityManager
|
||||
* @param armorTier The armor tier for which to figure out the maximum durability.
|
||||
* @return The maximum durability of the armor tier.
|
||||
*/
|
||||
private int calculateMaxDurability(ArmorTier armorTier)
|
||||
{
|
||||
if (armorTier == ArmorTier.NONE || !config.useTierDurability())
|
||||
private int calculateMaxDurability(ArmorTier armorTier) {
|
||||
if (armorTier == ArmorTier.NONE || !config.useTierDurability()) {
|
||||
return ELYTRA_MAX_DURABILITY;
|
||||
}
|
||||
return ArmorTier.getMaxDurability(armorTier);
|
||||
}
|
||||
|
||||
@ -233,8 +231,7 @@ public class DurabilityManager
|
||||
* @param armorTier The armor tier for which to check.
|
||||
* @return True if the provided durability should be considered 'broken' for the provided armor tier.
|
||||
*/
|
||||
public boolean isBroken(int durability, ArmorTier armorTier)
|
||||
{
|
||||
public boolean isBroken(int durability, ArmorTier armorTier) {
|
||||
return durability >= getMaxDurability(armorTier);
|
||||
}
|
||||
|
||||
@ -245,11 +242,11 @@ public class DurabilityManager
|
||||
* @param armorTier The armor tier for which to check.
|
||||
* @return True if the provided armored elytra should be considered 'broken'.
|
||||
*/
|
||||
public boolean isBroken(ItemStack armoredElytra, @Nullable ArmorTier armorTier)
|
||||
{
|
||||
public boolean isBroken(ItemStack armoredElytra, @Nullable ArmorTier armorTier) {
|
||||
final int realDurability = getRealDurability(armoredElytra, armorTier);
|
||||
if (realDurability == 0)
|
||||
if (realDurability == 0) {
|
||||
return false;
|
||||
}
|
||||
return isBroken(realDurability, armorTier == null ? nbtEditor.getArmorTier(armoredElytra) : armorTier);
|
||||
}
|
||||
|
||||
@ -259,8 +256,7 @@ public class DurabilityManager
|
||||
* @param armorTier The armor tier for which to get the maximum durability.
|
||||
* @return The maximum durability of the given armor tier.
|
||||
*/
|
||||
private int getMaxDurability(ArmorTier armorTier)
|
||||
{
|
||||
private int getMaxDurability(ArmorTier armorTier) {
|
||||
return maxDurabilities[armorTier.ordinal()];
|
||||
}
|
||||
|
||||
@ -270,8 +266,7 @@ public class DurabilityManager
|
||||
* @param armorTier The armor tier.
|
||||
* @return The amount of durability restored per repair step for the given armor tier.
|
||||
*/
|
||||
private int getRepairAmount(ArmorTier armorTier)
|
||||
{
|
||||
private int getRepairAmount(ArmorTier armorTier) {
|
||||
return repairAmounts[armorTier.ordinal()];
|
||||
}
|
||||
|
||||
@ -285,8 +280,7 @@ public class DurabilityManager
|
||||
* @return The new durability value after remapping it to the new maximum. The value cannot be less than 0 or more
|
||||
* than newMax.
|
||||
*/
|
||||
private int getRemappedDurability(int durability, int oldMax, int newMax)
|
||||
{
|
||||
private int getRemappedDurability(int durability, int oldMax, int newMax) {
|
||||
final float relativeDurability = (float) durability / oldMax;
|
||||
return Util.between((int) Math.ceil(relativeDurability * newMax), 0, newMax);
|
||||
}
|
||||
@ -294,14 +288,12 @@ public class DurabilityManager
|
||||
/**
|
||||
* Initializes the {@link #maxDurabilities} and {@link #repairAmounts} arrays.
|
||||
*/
|
||||
private void init()
|
||||
{
|
||||
private void init() {
|
||||
repairAmounts[0] = 0;
|
||||
maxDurabilities[0] = ELYTRA_MAX_DURABILITY;
|
||||
|
||||
final ArmorTier[] armorTiers = ArmorTier.values();
|
||||
for (int idx = 1; idx < armorTiers.length; ++idx)
|
||||
{
|
||||
for (int idx = 1; idx < armorTiers.length; ++idx) {
|
||||
final ArmorTier armorTier = armorTiers[idx];
|
||||
|
||||
final int maxDurability = calculateMaxDurability(armorTier);
|
||||
@ -319,8 +311,7 @@ public class DurabilityManager
|
||||
* @return The durability of the item.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private int getItemDurability(ItemStack item)
|
||||
{
|
||||
private int getItemDurability(ItemStack item) {
|
||||
return item.getDurability();
|
||||
}
|
||||
}
|
||||
|
@ -21,14 +21,13 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class NBTEditor
|
||||
{
|
||||
public class NBTEditor {
|
||||
private static final NamespacedKey ARMOR_TIER_KEY = new NamespacedKey(ArmoredElytra.getInstance(),
|
||||
"ARMOR_TIER_LEVEL");
|
||||
"ARMOR_TIER_LEVEL");
|
||||
private static final NamespacedKey ARMOR_COLOR_KEY = new NamespacedKey(ArmoredElytra.getInstance(),
|
||||
"ARMORED_ELYTRA_COLOR");
|
||||
"ARMORED_ELYTRA_COLOR");
|
||||
private static final NamespacedKey DURABILITY_KEY = new NamespacedKey(ArmoredElytra.getInstance(),
|
||||
"ARMORED_ELYTRA_DURABILITY");
|
||||
"ARMORED_ELYTRA_DURABILITY");
|
||||
|
||||
/**
|
||||
* Gets the real durability value as stored in the NBT of an armored elytra.
|
||||
@ -37,20 +36,21 @@ public class NBTEditor
|
||||
* @param providedTier The armor tier of the armored elytra. If this is null, it will be retrieved from NBT.
|
||||
* @return The real durability of the itemstack if the itemstack has the AE durability attribute, or -1 otherwise.
|
||||
*/
|
||||
public int getRealDurability(ItemStack itemStack, @Nullable ArmorTier providedTier)
|
||||
{
|
||||
public int getRealDurability(ItemStack itemStack, @Nullable ArmorTier providedTier) {
|
||||
final @Nullable ItemMeta meta = itemStack.getItemMeta();
|
||||
final ArmorTier armorTier = providedTier == null ? getArmorTier(meta) : providedTier;
|
||||
|
||||
if (armorTier == ArmorTier.NONE)
|
||||
if (armorTier == ArmorTier.NONE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(meta instanceof Damageable))
|
||||
if (!(meta instanceof Damageable)) {
|
||||
throw new IllegalStateException("Item \"" + itemStack + "\" with meta \"" + meta + "\" is not Damageable!");
|
||||
}
|
||||
|
||||
final @Nullable Integer realDurability =
|
||||
Objects.requireNonNull(meta, "Meta cannot be null for armored elytras!")
|
||||
.getPersistentDataContainer().get(DURABILITY_KEY, PersistentDataType.INTEGER);
|
||||
Objects.requireNonNull(meta, "Meta cannot be null for armored elytras!")
|
||||
.getPersistentDataContainer().get(DURABILITY_KEY, PersistentDataType.INTEGER);
|
||||
|
||||
return realDurability == null ? -1 : realDurability;
|
||||
}
|
||||
@ -63,13 +63,13 @@ public class NBTEditor
|
||||
* @param displayDurability The durability value to display on the item. This is the durability value the client can
|
||||
* actually see.This only works if the item's meta is an instance of {@link Damageable}.
|
||||
*/
|
||||
public void updateDurability(ItemStack itemStack, int realDurability, int displayDurability)
|
||||
{
|
||||
public void updateDurability(ItemStack itemStack, int realDurability, int displayDurability) {
|
||||
final ItemMeta meta = getOrCreateItemMeta(itemStack);
|
||||
meta.getPersistentDataContainer().set(DURABILITY_KEY, PersistentDataType.INTEGER, realDurability);
|
||||
|
||||
if (meta instanceof Damageable)
|
||||
if (meta instanceof Damageable) {
|
||||
((Damageable) meta).setDamage(displayDurability);
|
||||
}
|
||||
|
||||
itemStack.setItemMeta(meta);
|
||||
}
|
||||
@ -87,67 +87,73 @@ public class NBTEditor
|
||||
* @return The NEW item.
|
||||
*/
|
||||
public ItemStack addArmorNBTTags(ItemStack item, ArmorTier armorTier, boolean unbreakable, String name,
|
||||
@Nullable List<String> lore, @Nullable Color color)
|
||||
{
|
||||
if (armorTier == null || armorTier == ArmorTier.NONE)
|
||||
@Nullable List<String> lore, @Nullable Color color) {
|
||||
if (armorTier == null || armorTier == ArmorTier.NONE) {
|
||||
return new ItemStack(item);
|
||||
}
|
||||
|
||||
final ItemStack ret = new ItemStack(item);
|
||||
final ItemMeta meta = getOrCreateItemMeta(ret);
|
||||
meta.getPersistentDataContainer().set(ARMOR_TIER_KEY, PersistentDataType.INTEGER,
|
||||
ArmorTier.getTierID(armorTier));
|
||||
ArmorTier.getTierID(armorTier));
|
||||
|
||||
if (color != null && armorTier == ArmorTier.LEATHER)
|
||||
if (color != null && armorTier == ArmorTier.LEATHER) {
|
||||
meta.getPersistentDataContainer().set(ARMOR_COLOR_KEY, PersistentDataType.INTEGER, color.asRGB());
|
||||
}
|
||||
|
||||
overwriteNBTValue(meta, Attribute.GENERIC_ARMOR, ArmorTier.getArmor(armorTier), "generic.armor");
|
||||
if (ArmorTier.getToughness(armorTier) > 0)
|
||||
if (ArmorTier.getToughness(armorTier) > 0) {
|
||||
overwriteNBTValue(meta, Attribute.GENERIC_ARMOR_TOUGHNESS, ArmorTier.getToughness(armorTier),
|
||||
"generic.armor_toughness");
|
||||
"generic.armor_toughness");
|
||||
}
|
||||
|
||||
if (ArmorTier.getKnockbackResistance(armorTier) > 0)
|
||||
if (ArmorTier.getKnockbackResistance(armorTier) > 0) {
|
||||
overwriteNBTValue(meta, Attribute.GENERIC_KNOCKBACK_RESISTANCE, ArmorTier.getKnockbackResistance(armorTier),
|
||||
"generic.knockback_resistance");
|
||||
"generic.knockback_resistance");
|
||||
}
|
||||
|
||||
meta.setUnbreakable(unbreakable);
|
||||
meta.setDisplayName(name);
|
||||
if (lore != null)
|
||||
if (lore != null) {
|
||||
meta.setLore(lore);
|
||||
}
|
||||
|
||||
ret.setItemMeta(meta);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void overwriteNBTValue(ItemMeta meta, Attribute attribute, double value, String modifierName)
|
||||
{
|
||||
if (meta.hasAttributeModifiers())
|
||||
void overwriteNBTValue(ItemMeta meta, Attribute attribute, double value, String modifierName) {
|
||||
if (meta.hasAttributeModifiers()) {
|
||||
meta.removeAttributeModifier(attribute);
|
||||
}
|
||||
|
||||
final AttributeModifier attributeModifier = new AttributeModifier(UUID.randomUUID(), modifierName, value,
|
||||
AttributeModifier.Operation.ADD_NUMBER,
|
||||
EquipmentSlot.CHEST);
|
||||
AttributeModifier.Operation.ADD_NUMBER,
|
||||
EquipmentSlot.CHEST);
|
||||
meta.addAttributeModifier(attribute, attributeModifier);
|
||||
}
|
||||
|
||||
ArmorTier getArmorTier(@Nullable ItemMeta meta)
|
||||
{
|
||||
if (meta == null || !meta.hasAttributeModifiers())
|
||||
ArmorTier getArmorTier(@Nullable ItemMeta meta) {
|
||||
if (meta == null || !meta.hasAttributeModifiers()) {
|
||||
return ArmorTier.NONE;
|
||||
}
|
||||
|
||||
final @Nullable Integer tierID = meta.getPersistentDataContainer()
|
||||
.get(ARMOR_TIER_KEY, PersistentDataType.INTEGER);
|
||||
if (tierID != null)
|
||||
.get(ARMOR_TIER_KEY, PersistentDataType.INTEGER);
|
||||
if (tierID != null) {
|
||||
return ArmorTier.getArmorTierFromID(tierID);
|
||||
}
|
||||
|
||||
final Collection<AttributeModifier> attributeModifiers = meta.getAttributeModifiers(Attribute.GENERIC_ARMOR);
|
||||
if (attributeModifiers == null)
|
||||
if (attributeModifiers == null) {
|
||||
return ArmorTier.NONE;
|
||||
}
|
||||
|
||||
for (final AttributeModifier attributeModifier : attributeModifiers)
|
||||
{
|
||||
for (final AttributeModifier attributeModifier : attributeModifiers) {
|
||||
final ArmorTier armorTier = ArmorTier.getArmorTierFromArmor((int) attributeModifier.getAmount());
|
||||
if (armorTier != ArmorTier.NONE)
|
||||
if (armorTier != ArmorTier.NONE) {
|
||||
return armorTier;
|
||||
}
|
||||
}
|
||||
|
||||
return ArmorTier.NONE;
|
||||
@ -159,10 +165,10 @@ public class NBTEditor
|
||||
* @param item The item to check.
|
||||
* @return The {@link ArmorTier} that is on the item. If none is found, {@link ArmorTier#NONE} is returned.
|
||||
*/
|
||||
public ArmorTier getArmorTier(@Nullable ItemStack item)
|
||||
{
|
||||
if (item == null)
|
||||
public ArmorTier getArmorTier(@Nullable ItemStack item) {
|
||||
if (item == null) {
|
||||
return ArmorTier.NONE;
|
||||
}
|
||||
return getArmorTier(item.getItemMeta());
|
||||
}
|
||||
|
||||
@ -172,8 +178,7 @@ public class NBTEditor
|
||||
* @param item The item to check. This may or may not be an armored elytra.
|
||||
* @return True if the item exists and is unbreakable. Otherwise, false.
|
||||
*/
|
||||
public boolean isUnbreakable(@Nullable ItemStack item)
|
||||
{
|
||||
public boolean isUnbreakable(@Nullable ItemStack item) {
|
||||
final @Nullable ItemMeta meta = item == null ? null : item.getItemMeta();
|
||||
return meta != null && meta.isUnbreakable();
|
||||
}
|
||||
@ -186,30 +191,32 @@ public class NBTEditor
|
||||
* @param item The armored elytra to check.
|
||||
* @return The color of the armored elytra, if the input is a colored armored elytra, otherwise null.
|
||||
*/
|
||||
public Color getColorOfArmoredElytra(@Nullable ItemStack item)
|
||||
{
|
||||
if (item == null || item.getType() != Material.ELYTRA || !item.hasItemMeta())
|
||||
public Color getColorOfArmoredElytra(@Nullable ItemStack item) {
|
||||
if (item == null || item.getType() != Material.ELYTRA || !item.hasItemMeta()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final ItemMeta meta = item.getItemMeta();
|
||||
if (meta == null)
|
||||
if (meta == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||
if (!container.has(ARMOR_COLOR_KEY, PersistentDataType.INTEGER))
|
||||
if (!container.has(ARMOR_COLOR_KEY, PersistentDataType.INTEGER)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Integer rgb = container.get(ARMOR_COLOR_KEY, PersistentDataType.INTEGER);
|
||||
return rgb == null ? null : Color.fromRGB(rgb);
|
||||
}
|
||||
|
||||
static ItemMeta getOrCreateItemMeta(ItemStack item)
|
||||
{
|
||||
static ItemMeta getOrCreateItemMeta(ItemStack item) {
|
||||
final ItemMeta meta = item.hasItemMeta() ?
|
||||
item.getItemMeta() :
|
||||
Bukkit.getItemFactory().getItemMeta(item.getType());
|
||||
if (meta == null)
|
||||
item.getItemMeta() :
|
||||
Bukkit.getItemFactory().getItemMeta(item.getType());
|
||||
if (meta == null) {
|
||||
throw new IllegalArgumentException("Tried to add armor to invalid item: " + item);
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package nl.pim16aap2.armoredElytra.util;
|
||||
|
||||
public enum Action
|
||||
{
|
||||
public enum Action {
|
||||
/**
|
||||
* Take no action at all and let vanilla (or some other plugin) handle the process.
|
||||
*/
|
||||
|
@ -1,6 +1,5 @@
|
||||
package nl.pim16aap2.armoredElytra.util;
|
||||
|
||||
public enum AllowedToWearEnum
|
||||
{
|
||||
public enum AllowedToWearEnum {
|
||||
BROKEN, NOPERMISSION, ALLOWED
|
||||
}
|
||||
|
@ -5,8 +5,7 @@ import org.bukkit.Material;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum ArmorTier
|
||||
{
|
||||
public enum ArmorTier {
|
||||
// Tier: TierID, armor-value, armor-toughness, knockbackResistance, repair, defaultRepairCount, name, durability
|
||||
NONE(0, 0, 0, 0, null, 0, "", 0),
|
||||
LEATHER(1, 3, 0, 0, Material.LEATHER, 6, "leather", 80),
|
||||
@ -30,8 +29,7 @@ public enum ArmorTier
|
||||
private static final Map<Integer, ArmorTier> armorIDMap = new HashMap<>();
|
||||
|
||||
ArmorTier(int tierID, int armor, int toughness, double knockbackResistance, Material repair,
|
||||
int defaultRepairCount, String name, int durability)
|
||||
{
|
||||
int defaultRepairCount, String name, int durability) {
|
||||
this.tierID = tierID;
|
||||
this.armor = armor;
|
||||
this.toughness = toughness;
|
||||
@ -42,64 +40,52 @@ public enum ArmorTier
|
||||
this.durability = durability;
|
||||
}
|
||||
|
||||
public static int getArmor(ArmorTier tier)
|
||||
{
|
||||
public static int getArmor(ArmorTier tier) {
|
||||
return tier.armor;
|
||||
}
|
||||
|
||||
public static int getMaxDurability(ArmorTier tier)
|
||||
{
|
||||
public static int getMaxDurability(ArmorTier tier) {
|
||||
return tier.durability;
|
||||
}
|
||||
|
||||
public static int getTierID(ArmorTier tier)
|
||||
{
|
||||
public static int getTierID(ArmorTier tier) {
|
||||
return tier.tierID;
|
||||
}
|
||||
|
||||
public static int getToughness(ArmorTier tier)
|
||||
{
|
||||
public static int getToughness(ArmorTier tier) {
|
||||
return tier.toughness;
|
||||
}
|
||||
|
||||
// return the armor toughness of a tier.
|
||||
public static double getKnockbackResistance(ArmorTier tier)
|
||||
{
|
||||
public static double getKnockbackResistance(ArmorTier tier) {
|
||||
return tier.knockbackResistance;
|
||||
}
|
||||
|
||||
// return the repair item of a tier
|
||||
public static Material getRepairItem(ArmorTier tier)
|
||||
{
|
||||
public static Material getRepairItem(ArmorTier tier) {
|
||||
return tier.repair;
|
||||
}
|
||||
|
||||
public static String getName(ArmorTier tier)
|
||||
{
|
||||
public static String getName(ArmorTier tier) {
|
||||
return tier.name;
|
||||
}
|
||||
|
||||
public static ArmorTier valueOfName(String name)
|
||||
{
|
||||
public static ArmorTier valueOfName(String name) {
|
||||
return map.get(name);
|
||||
}
|
||||
|
||||
public static ArmorTier getArmorTierFromArmor(int armor)
|
||||
{
|
||||
public static ArmorTier getArmorTierFromArmor(int armor) {
|
||||
ArmorTier tier = armorValueMap.get(armor);
|
||||
return tier == null ? ArmorTier.NONE : tier;
|
||||
}
|
||||
|
||||
public static ArmorTier getArmorTierFromID(int tierID)
|
||||
{
|
||||
public static ArmorTier getArmorTierFromID(int tierID) {
|
||||
ArmorTier tier = armorIDMap.get(tierID);
|
||||
return tier == null ? ArmorTier.NONE : tier;
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
for (ArmorTier tier : ArmorTier.values())
|
||||
{
|
||||
static {
|
||||
for (ArmorTier tier : ArmorTier.values()) {
|
||||
map.put(tier.name, tier);
|
||||
armorValueMap.put(tier.armor, tier);
|
||||
armorIDMap.put(tier.tierID, tier);
|
||||
@ -113,8 +99,7 @@ public enum ArmorTier
|
||||
armorValueMap.put(ArmorTier.DIAMOND.armor, ArmorTier.DIAMOND);
|
||||
}
|
||||
|
||||
public static int getDefaultRepairCount(ArmorTier armorTier)
|
||||
{
|
||||
public static int getDefaultRepairCount(ArmorTier armorTier) {
|
||||
return armorTier.defaultRepairCount;
|
||||
}
|
||||
}
|
||||
|
@ -3,33 +3,27 @@ package nl.pim16aap2.armoredElytra.util;
|
||||
/**
|
||||
* @author Pim
|
||||
*/
|
||||
public class ArmorTierName
|
||||
{
|
||||
public class ArmorTierName {
|
||||
private String longName, shortName;
|
||||
|
||||
public ArmorTierName(final String longName, final String shortName)
|
||||
{
|
||||
public ArmorTierName(final String longName, final String shortName) {
|
||||
this.longName = longName;
|
||||
this.shortName = shortName;
|
||||
}
|
||||
|
||||
public String getLongName()
|
||||
{
|
||||
public String getLongName() {
|
||||
return longName;
|
||||
}
|
||||
|
||||
public String getShortName()
|
||||
{
|
||||
public String getShortName() {
|
||||
return shortName;
|
||||
}
|
||||
|
||||
public void setLongName(final String longName)
|
||||
{
|
||||
public void setLongName(final String longName) {
|
||||
this.longName = longName;
|
||||
}
|
||||
|
||||
public void setShortName(final String shortName)
|
||||
{
|
||||
public void setShortName(final String shortName) {
|
||||
this.shortName = shortName;
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,9 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class ConfigLoader
|
||||
{
|
||||
public class ConfigLoader {
|
||||
private static final String HEADER =
|
||||
"Config file for ArmoredElytra. Don't forget to make a backup before making changes!";
|
||||
"Config file for ArmoredElytra. Don't forget to make a backup before making changes!";
|
||||
|
||||
private final ArmoredElytra plugin;
|
||||
|
||||
@ -46,137 +45,135 @@ public class ConfigLoader
|
||||
private boolean allowRenaming;
|
||||
private boolean allowAddingEnchantments;
|
||||
|
||||
public ConfigLoader(ArmoredElytra plugin)
|
||||
{
|
||||
public ConfigLoader(ArmoredElytra plugin) {
|
||||
this.plugin = plugin;
|
||||
makeConfig();
|
||||
}
|
||||
|
||||
// Read the current config, the make a new one based on the old one or default values, whichever is applicable.
|
||||
private void makeConfig()
|
||||
{
|
||||
private void makeConfig() {
|
||||
// All the comments for the various config options.
|
||||
String[] unbreakableComment =
|
||||
{
|
||||
"Setting this to true will cause armored elytras to be unbreakable.",
|
||||
"Changing this to false will NOT make unbreakable elytras breakable again!"
|
||||
};
|
||||
{
|
||||
"Setting this to true will cause armored elytras to be unbreakable.",
|
||||
"Changing this to false will NOT make unbreakable elytras breakable again!"
|
||||
};
|
||||
String[] flyDurabilityComment =
|
||||
{
|
||||
"Setting this to true will cause armored elytras to not lose any durability while flying.",
|
||||
"This is not a permanent option and will affect ALL elytras."
|
||||
};
|
||||
{
|
||||
"Setting this to true will cause armored elytras to not lose any durability while flying.",
|
||||
"This is not a permanent option and will affect ALL elytras."
|
||||
};
|
||||
String[] useTierDurabilityComment =
|
||||
{
|
||||
"Use the maximum durability of the armor tier of armored elytras.",
|
||||
"For example, when this is true, a diamond armored elytra would have a durability of 528.",
|
||||
"When this is false, all armored elytras have the maximum durability of a regular elytra."
|
||||
};
|
||||
{
|
||||
"Use the maximum durability of the armor tier of armored elytras.",
|
||||
"For example, when this is true, a diamond armored elytra would have a durability of 528.",
|
||||
"When this is false, all armored elytras have the maximum durability of a regular elytra."
|
||||
};
|
||||
String[] repairComment =
|
||||
{
|
||||
"Amount of items it takes to fully repair an armored elytra",
|
||||
"Repair cost for every tier of armored elytra in number of items to repair 100%.",
|
||||
"Note that this value cannot be less than 1."
|
||||
};
|
||||
{
|
||||
"Amount of items it takes to fully repair an armored elytra",
|
||||
"Repair cost for every tier of armored elytra in number of items to repair 100%.",
|
||||
"Note that this value cannot be less than 1."
|
||||
};
|
||||
String[] enchantmentsComment =
|
||||
{
|
||||
"List of enchantments that are allowed to be put on an armored elytra.",
|
||||
"If you do not want to allow any enchantments at all, remove them all and add \"NONE\"",
|
||||
"You can find supported enchantments by running the command:",
|
||||
"\"armoredelytra listAvailableEnchantments\" in console",
|
||||
"If you install additional enchantment plugins, you can add their enchantments as well.",
|
||||
"Just add their 'NamespacedKey'. Ask the enchantment plugin dev for more info if you need it."
|
||||
};
|
||||
{
|
||||
"List of enchantments that are allowed to be put on an armored elytra.",
|
||||
"If you do not want to allow any enchantments at all, remove them all and add \"NONE\"",
|
||||
"You can find supported enchantments by running the command:",
|
||||
"\"armoredelytra listAvailableEnchantments\" in console",
|
||||
"If you install additional enchantment plugins, you can add their enchantments as well.",
|
||||
"Just add their 'NamespacedKey'. Ask the enchantment plugin dev for more info if you need it."
|
||||
};
|
||||
String[] mutuallyExclusiveEnchantmentsComment =
|
||||
{
|
||||
"The lists of enchantments that are mutually exclusive.",
|
||||
"Each group [] on this list is treated as mutually exclusive, " +
|
||||
"so only one of them can be on an ArmoredElytra.",
|
||||
"The default follows modern vanilla rules by making the different " +
|
||||
"types of protection mutually exclusive.",
|
||||
"If you do not want any enchantments to be mutually exclusive, " +
|
||||
"replace all the entries in this list with \"[]\"",
|
||||
"You can find supported enchantments by running the command:",
|
||||
"\"armoredelytra listAvailableEnchantments\" in console",
|
||||
"If you install additional enchant plugins, " +
|
||||
"you can make their enchantments mutually exclusive as well.",
|
||||
"Just add their 'NamespacedKey'. Ask the enchantment plugin dev for more info if you need it."
|
||||
};
|
||||
{
|
||||
"The lists of enchantments that are mutually exclusive.",
|
||||
"Each group [] on this list is treated as mutually exclusive, " +
|
||||
"so only one of them can be on an ArmoredElytra.",
|
||||
"The default follows modern vanilla rules by making the different " +
|
||||
"types of protection mutually exclusive.",
|
||||
"If you do not want any enchantments to be mutually exclusive, " +
|
||||
"replace all the entries in this list with \"[]\"",
|
||||
"You can find supported enchantments by running the command:",
|
||||
"\"armoredelytra listAvailableEnchantments\" in console",
|
||||
"If you install additional enchant plugins, " +
|
||||
"you can make their enchantments mutually exclusive as well.",
|
||||
"Just add their 'NamespacedKey'. Ask the enchantment plugin dev for more info if you need it."
|
||||
};
|
||||
String[] dropNetheriteAsChestplateComment =
|
||||
{
|
||||
"Whether to drop Netherite Armored Elytras as netherite chestplates when they are dropped",
|
||||
"This means that they won't burn in lava etc.",
|
||||
"When you pick them up, they will turn into Netherite Armored Elytras again."
|
||||
};
|
||||
{
|
||||
"Whether to drop Netherite Armored Elytras as netherite chestplates when they are dropped",
|
||||
"This means that they won't burn in lava etc.",
|
||||
"When you pick them up, they will turn into Netherite Armored Elytras again."
|
||||
};
|
||||
String[] updateComment =
|
||||
{
|
||||
"Allow this plugin to check for updates on startup. It will not download new versions on its own!"
|
||||
};
|
||||
{
|
||||
"Allow this plugin to check for updates on startup. It will not download new versions on its own!"
|
||||
};
|
||||
String[] bStatsComment =
|
||||
{
|
||||
"Allow this plugin to send (anonymous) stats using bStats. Please consider keeping it enabled.",
|
||||
"It has a negligible impact on performance and more users on stats keeps me more motivated " +
|
||||
"to support this plugin!"
|
||||
};
|
||||
{
|
||||
"Allow this plugin to send (anonymous) stats using bStats. Please consider keeping it enabled.",
|
||||
"It has a negligible impact on performance and more users on stats keeps me more motivated " +
|
||||
"to support this plugin!"
|
||||
};
|
||||
String[] debugComment =
|
||||
{
|
||||
"Print debug messages to console. You will most likely never need this."
|
||||
};
|
||||
{
|
||||
"Print debug messages to console. You will most likely never need this."
|
||||
};
|
||||
String[] uninstallComment =
|
||||
{
|
||||
"Setting this to true will disable this plugin and remove any armored elytras it can find.",
|
||||
"It will check player's inventories and their end chest upon login and any regular" +
|
||||
" chest when it is opened.",
|
||||
"This means it will take a while for all armored elytras to be removed from your server, " +
|
||||
"but it doesn't take up ",
|
||||
"a lot of resources, so you can just leave the plugin enabled and ignore it.",
|
||||
"Please do not forget to MAKE A BACKUP before enabling this option!"
|
||||
};
|
||||
{
|
||||
"Setting this to true will disable this plugin and remove any armored elytras it can find.",
|
||||
"It will check player's inventories and their end chest upon login and any regular" +
|
||||
" chest when it is opened.",
|
||||
"This means it will take a while for all armored elytras to be removed from your server, " +
|
||||
"but it doesn't take up ",
|
||||
"a lot of resources, so you can just leave the plugin enabled and ignore it.",
|
||||
"Please do not forget to MAKE A BACKUP before enabling this option!"
|
||||
};
|
||||
String[] languageFileComment =
|
||||
{
|
||||
"Specify a language file to be used."
|
||||
};
|
||||
{
|
||||
"Specify a language file to be used."
|
||||
};
|
||||
String[] permissionsComment =
|
||||
{
|
||||
"Globally bypass permissions for wearing and/or crafting armored elytras.",
|
||||
"Useful if permissions are unavailable."
|
||||
};
|
||||
{
|
||||
"Globally bypass permissions for wearing and/or crafting armored elytras.",
|
||||
"Useful if permissions are unavailable."
|
||||
};
|
||||
String[] craftingInSmithingTableComment =
|
||||
{
|
||||
"When enabled, armored elytra creation in anvils is disabled. ",
|
||||
"Instead, you will have to craft them in a smithy. Enchanting/repairing them still works via the anvil."
|
||||
};
|
||||
{
|
||||
"When enabled, armored elytra creation in anvils is disabled. ",
|
||||
"Instead, you will have to craft them in a smithy. Enchanting/repairing them still works via the anvil."
|
||||
};
|
||||
String[] allowUpgradeToNetheriteComment =
|
||||
{
|
||||
"Whether or not to allow upgrading diamond armored elytras to netherite ones is possible.",
|
||||
"When allowed, you can combine a diamond one with a netherite ingot in a smithing table",
|
||||
"and you'll receive a netherite one."
|
||||
};
|
||||
{
|
||||
"Whether or not to allow upgrading diamond armored elytras to netherite ones is possible.",
|
||||
"When allowed, you can combine a diamond one with a netherite ingot in a smithing table",
|
||||
"and you'll receive a netherite one."
|
||||
};
|
||||
String[] allowRenamingComment =
|
||||
{
|
||||
"Whether or not to allow renaming of armored elytras in anvils."
|
||||
};
|
||||
{
|
||||
"Whether or not to allow renaming of armored elytras in anvils."
|
||||
};
|
||||
String[] allowAddingEnchantmentsComment =
|
||||
{
|
||||
"Allow new enchantments to be added to armored elytras.",
|
||||
"When false, no enchantments can be added to armored elytras, even those on the allowed list.",
|
||||
"When true, only enchantments from the allowed list can be added."
|
||||
};
|
||||
{
|
||||
"Allow new enchantments to be added to armored elytras.",
|
||||
"When false, no enchantments can be added to armored elytras, even those on the allowed list.",
|
||||
"When true, only enchantments from the allowed list can be added."
|
||||
};
|
||||
|
||||
// Set default list of allowed enchantments.
|
||||
List<String> defaultAllowedEnchantments = new ArrayList<>(
|
||||
Arrays.asList("minecraft:unbreaking", "minecraft:fire_protection", "minecraft:blast_protection",
|
||||
"minecraft:projectile_protection", "minecraft:protection",
|
||||
"minecraft:thorns", "minecraft:binding_curse", "minecraft:vanishing_curse",
|
||||
"minecraft:mending"));
|
||||
Arrays.asList("minecraft:unbreaking", "minecraft:fire_protection", "minecraft:blast_protection",
|
||||
"minecraft:projectile_protection", "minecraft:protection",
|
||||
"minecraft:thorns", "minecraft:binding_curse", "minecraft:vanishing_curse",
|
||||
"minecraft:mending"));
|
||||
|
||||
// Set a default list of lists of mutually exclusive enchantments
|
||||
// Default only has a list for the protection enchantments
|
||||
List<List<String>> defaultMutuallyExclusiveEnchantments = new ArrayList<>();
|
||||
defaultMutuallyExclusiveEnchantments.add(List.of("minecraft:protection",
|
||||
"minecraft:projectile_protection",
|
||||
"minecraft:blast_protection",
|
||||
"minecraft:fire_protection"));
|
||||
"minecraft:projectile_protection",
|
||||
"minecraft:blast_protection",
|
||||
"minecraft:fire_protection"));
|
||||
|
||||
FileConfiguration config = plugin.getConfig();
|
||||
|
||||
@ -186,8 +183,7 @@ public class ConfigLoader
|
||||
useTierDurability = addNewConfigOption(config, "useTierDurability", true, useTierDurabilityComment);
|
||||
|
||||
final ArmorTier[] armorTiers = ArmorTier.values();
|
||||
for (int idx = 1; idx < armorTiers.length; ++idx)
|
||||
{
|
||||
for (int idx = 1; idx < armorTiers.length; ++idx) {
|
||||
final ArmorTier armorTier = armorTiers[idx];
|
||||
|
||||
// Only the first one should have the comment.
|
||||
@ -199,31 +195,32 @@ public class ConfigLoader
|
||||
}
|
||||
|
||||
final int armorTierCount = ArmorTier.values().length;
|
||||
if (repairCounts.length != armorTierCount)
|
||||
if (repairCounts.length != armorTierCount) {
|
||||
throw new IllegalStateException("Incorrect repair counts array size! Expected size " +
|
||||
armorTierCount + " but got size " + repairCounts.length);
|
||||
armorTierCount + " but got size " + repairCounts.length);
|
||||
}
|
||||
|
||||
craftingInSmithingTable = addNewConfigOption(config, "craftingInSmithingTable", true,
|
||||
craftingInSmithingTableComment);
|
||||
craftingInSmithingTableComment);
|
||||
allowUpgradeToNetherite = addNewConfigOption(config, "allowUpgradeToNetherite", true,
|
||||
allowUpgradeToNetheriteComment);
|
||||
allowUpgradeToNetheriteComment);
|
||||
|
||||
defaultAllowedEnchantments = addNewConfigOption(config, "allowedEnchantments", defaultAllowedEnchantments,
|
||||
enchantmentsComment);
|
||||
enchantmentsComment);
|
||||
allowedEnchantments = new LinkedHashSet<>();
|
||||
defaultAllowedEnchantments.forEach(this::addNameSpacedKey);
|
||||
|
||||
defaultMutuallyExclusiveEnchantments =
|
||||
addNewConfigOption(config, "mutuallyExclusiveEnchantments",
|
||||
defaultMutuallyExclusiveEnchantments, mutuallyExclusiveEnchantmentsComment);
|
||||
addNewConfigOption(config, "mutuallyExclusiveEnchantments",
|
||||
defaultMutuallyExclusiveEnchantments, mutuallyExclusiveEnchantmentsComment);
|
||||
mutuallyExclusiveEnchantments = new LinkedList<>();
|
||||
defaultMutuallyExclusiveEnchantments.forEach(this::addMutuallyExclusiveEnchantments);
|
||||
|
||||
allowAddingEnchantments = addNewConfigOption(config, "allowAddingEnchantments", true,
|
||||
allowAddingEnchantmentsComment);
|
||||
allowAddingEnchantmentsComment);
|
||||
allowRenaming = addNewConfigOption(config, "allowRenaming", true, allowRenamingComment);
|
||||
dropNetheriteAsChestplate = addNewConfigOption(config, "dropNetheriteAsChestplate", true,
|
||||
dropNetheriteAsChestplateComment);
|
||||
dropNetheriteAsChestplateComment);
|
||||
|
||||
checkForUpdates = addNewConfigOption(config, "checkForUpdates", true, updateComment);
|
||||
allowStats = addNewConfigOption(config, "allowStats", true, bStatsComment);
|
||||
@ -236,178 +233,149 @@ public class ConfigLoader
|
||||
writeConfig();
|
||||
}
|
||||
|
||||
private @Nullable Enchantment enchantmentFromNameSpacedKey(String fullKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
private @Nullable Enchantment enchantmentFromNameSpacedKey(String fullKey) {
|
||||
try {
|
||||
final String[] keyParts = fullKey.strip().split(":", 2);
|
||||
if (keyParts.length < 2)
|
||||
{
|
||||
if (keyParts.length < 2) {
|
||||
Bukkit.getLogger().warning("\"" + fullKey + "\" is not a valid NamespacedKey!");
|
||||
return null;
|
||||
}
|
||||
//noinspection deprecation
|
||||
final NamespacedKey key = new NamespacedKey(keyParts[0], keyParts[1]);
|
||||
final Enchantment enchantment = Enchantment.getByKey(key);
|
||||
if (enchantment == null)
|
||||
{
|
||||
if (enchantment == null) {
|
||||
Bukkit.getLogger().warning("The enchantment \"" + fullKey + "\" could not be found!");
|
||||
return null;
|
||||
}
|
||||
return enchantment;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().log(Level.WARNING, e, () -> "Failed to register NamespacedKey key: '" + fullKey + "'");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void addNameSpacedKey(String fullKey)
|
||||
{
|
||||
private void addNameSpacedKey(String fullKey) {
|
||||
final @Nullable Enchantment enchantment = enchantmentFromNameSpacedKey(fullKey);
|
||||
if (enchantment != null)
|
||||
if (enchantment != null) {
|
||||
allowedEnchantments.add(enchantment);
|
||||
}
|
||||
}
|
||||
|
||||
private void addMutuallyExclusiveEnchantments(List<String> fullKeys)
|
||||
{
|
||||
private void addMutuallyExclusiveEnchantments(List<String> fullKeys) {
|
||||
final List<Enchantment> enchantments = new LinkedList<>();
|
||||
for (String fullKey : fullKeys)
|
||||
{
|
||||
for (String fullKey : fullKeys) {
|
||||
final @Nullable Enchantment enchantment = enchantmentFromNameSpacedKey(fullKey);
|
||||
if (enchantment != null)
|
||||
if (enchantment != null) {
|
||||
enchantments.add(enchantment);
|
||||
}
|
||||
}
|
||||
mutuallyExclusiveEnchantments.add(enchantments);
|
||||
}
|
||||
|
||||
private <T> T addNewConfigOption(FileConfiguration config, String optionName, T defaultValue, String[] comment)
|
||||
{
|
||||
private <T> T addNewConfigOption(FileConfiguration config, String optionName, T defaultValue, String[] comment) {
|
||||
ConfigOption<T> option = new ConfigOption<>(plugin, config, optionName, defaultValue, comment);
|
||||
configOptionsList.add(option);
|
||||
return option.getValue();
|
||||
}
|
||||
|
||||
// Write new config file.
|
||||
private void writeConfig()
|
||||
{
|
||||
private void writeConfig() {
|
||||
// Write all the config options to the config.yml.
|
||||
try
|
||||
{
|
||||
try {
|
||||
final Path dataDir = plugin.getDataFolder().toPath();
|
||||
if (!Files.exists(dataDir))
|
||||
if (!Files.exists(dataDir)) {
|
||||
Files.createDirectory(dataDir);
|
||||
}
|
||||
|
||||
final Path configFile = dataDir.resolve("config.yml");
|
||||
|
||||
final StringBuilder sb = new StringBuilder(6000);
|
||||
sb.append("# ").append(HEADER).append('\n');
|
||||
for (final ConfigOption<?> configOption : configOptionsList)
|
||||
{
|
||||
if (configOption.hasComment())
|
||||
for (final ConfigOption<?> configOption : configOptionsList) {
|
||||
if (configOption.hasComment()) {
|
||||
sb.append('\n');
|
||||
}
|
||||
sb.append(configOption).append('\n');
|
||||
}
|
||||
|
||||
Files.write(configFile, sb.toString().getBytes(),
|
||||
StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not save config.yml! " +
|
||||
"Please contact pim16aap2 and show him the following code:");
|
||||
"Please contact pim16aap2 and show him the following code:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean allowStats()
|
||||
{
|
||||
public boolean allowStats() {
|
||||
return allowStats;
|
||||
}
|
||||
|
||||
public boolean craftingInSmithingTable()
|
||||
{
|
||||
public boolean craftingInSmithingTable() {
|
||||
return craftingInSmithingTable;
|
||||
}
|
||||
|
||||
public boolean allowUpgradeToNetherite()
|
||||
{
|
||||
public boolean allowUpgradeToNetherite() {
|
||||
return allowUpgradeToNetherite;
|
||||
}
|
||||
|
||||
public boolean unbreakable()
|
||||
{
|
||||
public boolean unbreakable() {
|
||||
return unbreakable;
|
||||
}
|
||||
|
||||
public boolean enableDebug()
|
||||
{
|
||||
public boolean enableDebug() {
|
||||
return enableDebug;
|
||||
}
|
||||
|
||||
public String languageFile()
|
||||
{
|
||||
public String languageFile() {
|
||||
return languageFile;
|
||||
}
|
||||
|
||||
public int getFullRepairItemCount(ArmorTier armorTier)
|
||||
{
|
||||
public int getFullRepairItemCount(ArmorTier armorTier) {
|
||||
return repairCounts[armorTier.ordinal()];
|
||||
}
|
||||
|
||||
public boolean allowRenaming()
|
||||
{
|
||||
public boolean allowRenaming() {
|
||||
return allowRenaming;
|
||||
}
|
||||
|
||||
public boolean allowAddingEnchantments()
|
||||
{
|
||||
public boolean allowAddingEnchantments() {
|
||||
return allowAddingEnchantments;
|
||||
}
|
||||
|
||||
public boolean uninstallMode()
|
||||
{
|
||||
public boolean uninstallMode() {
|
||||
return uninstallMode;
|
||||
}
|
||||
|
||||
public boolean checkForUpdates()
|
||||
{
|
||||
public boolean checkForUpdates() {
|
||||
return checkForUpdates;
|
||||
}
|
||||
|
||||
public boolean noFlightDurability()
|
||||
{
|
||||
public boolean noFlightDurability() {
|
||||
return noFlightDurability;
|
||||
}
|
||||
|
||||
public boolean dropNetheriteAsChestplate()
|
||||
{
|
||||
public boolean dropNetheriteAsChestplate() {
|
||||
return dropNetheriteAsChestplate;
|
||||
}
|
||||
|
||||
public LinkedHashSet<Enchantment> allowedEnchantments()
|
||||
{
|
||||
public LinkedHashSet<Enchantment> allowedEnchantments() {
|
||||
return allowedEnchantments;
|
||||
}
|
||||
|
||||
public List<List<Enchantment>> getMutuallyExclusiveEnchantments()
|
||||
{
|
||||
public List<List<Enchantment>> getMutuallyExclusiveEnchantments() {
|
||||
return mutuallyExclusiveEnchantments;
|
||||
}
|
||||
|
||||
public boolean bypassWearPerm()
|
||||
{
|
||||
public boolean bypassWearPerm() {
|
||||
return bypassWearPerm;
|
||||
}
|
||||
|
||||
public boolean bypassCraftPerm()
|
||||
{
|
||||
public boolean bypassCraftPerm() {
|
||||
return bypassCraftPerm;
|
||||
}
|
||||
|
||||
public boolean useTierDurability()
|
||||
{
|
||||
public boolean useTierDurability() {
|
||||
return useTierDurability;
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,7 @@ import java.util.List;
|
||||
* For Lists, every option appears on a new line after a '-'.
|
||||
*/
|
||||
|
||||
public class ConfigOption<V>
|
||||
{
|
||||
public class ConfigOption<V> {
|
||||
private final ArmoredElytra plugin;
|
||||
private final FileConfiguration config;
|
||||
private final String optionName;
|
||||
@ -22,8 +21,7 @@ public class ConfigOption<V>
|
||||
private final String[] comment;
|
||||
|
||||
public ConfigOption(ArmoredElytra plugin, FileConfiguration config, String optionName, V defaultValue,
|
||||
String[] comment)
|
||||
{
|
||||
String[] comment) {
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
this.optionName = optionName;
|
||||
@ -33,63 +31,55 @@ public class ConfigOption<V>
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void setValue()
|
||||
{
|
||||
try
|
||||
{
|
||||
private void setValue() {
|
||||
try {
|
||||
value = (V) config.get(optionName, defaultValue);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
} catch (Exception e) {
|
||||
plugin.myLogger(java.util.logging.Level.WARNING, "Failed to read config value of: \"" + optionName +
|
||||
"\"! Using default value instead!");
|
||||
"\"! Using default value instead!");
|
||||
plugin.myLogger(java.util.logging.Level.WARNING, Util.exceptionToString(e));
|
||||
value = defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public V getValue()
|
||||
{
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public @Nullable String[] getComment()
|
||||
{
|
||||
public @Nullable String[] getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public boolean hasComment()
|
||||
{
|
||||
public boolean hasComment() {
|
||||
return comment != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
String string = "";
|
||||
public String toString() {
|
||||
StringBuilder string = new StringBuilder();
|
||||
|
||||
// Print the comments, if there are any.
|
||||
if (comment != null)
|
||||
if (comment != null) {
|
||||
for (String comLine : comment)
|
||||
// Prefix every line by a comment-sign (#).
|
||||
string += "# " + comLine + "\n";
|
||||
string.append("# ").append(comLine).append("\n");
|
||||
}
|
||||
|
||||
string += optionName + ": ";
|
||||
if (value.getClass().isAssignableFrom(String.class))
|
||||
string += "\'" + value.toString() + "\'";
|
||||
else if (value instanceof List<?>)
|
||||
{
|
||||
string.append(optionName).append(": ");
|
||||
if (value.getClass().isAssignableFrom(String.class)) {
|
||||
string.append("\'").append(value).append("\'");
|
||||
} else if (value instanceof List<?>) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("\n");
|
||||
int listSize = ((List<?>) value).size();
|
||||
for (int index = 0; index < listSize; ++index)
|
||||
// Don't print newline at the end
|
||||
builder.append(" - " + ((List<?>) value).get(index) + (index == listSize - 1 ? "" : "\n"));
|
||||
string += builder.toString();
|
||||
builder.append(" - ").append(((List<?>) value).get(index)).append(index == listSize - 1 ? "" : "\n");
|
||||
string.append(builder);
|
||||
} else {
|
||||
string.append(value);
|
||||
}
|
||||
else
|
||||
string += value.toString();
|
||||
|
||||
return string;
|
||||
return string.toString();
|
||||
}
|
||||
}
|
||||
|
@ -14,8 +14,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Integer>>
|
||||
{
|
||||
public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Integer>> {
|
||||
private Map<Enchantment, Integer> enchantments;
|
||||
|
||||
/**
|
||||
@ -25,8 +24,7 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
* @param plugin The {@link ArmoredElytra} instance to use for obtaining the list of allowed enchantments. See
|
||||
* {@link ConfigLoader#allowedEnchantments()}.
|
||||
*/
|
||||
public EnchantmentContainer(final Map<Enchantment, Integer> enchantments, final ArmoredElytra plugin)
|
||||
{
|
||||
public EnchantmentContainer(final Map<Enchantment, Integer> enchantments, final ArmoredElytra plugin) {
|
||||
this(enchantments);
|
||||
filter(plugin.getConfigLoader().allowedEnchantments());
|
||||
filterMutuallyExclusive();
|
||||
@ -35,18 +33,15 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
public EnchantmentContainer(EnchantmentContainer other)
|
||||
{
|
||||
public EnchantmentContainer(EnchantmentContainer other) {
|
||||
this(other.enchantments);
|
||||
}
|
||||
|
||||
public EnchantmentContainer()
|
||||
{
|
||||
public EnchantmentContainer() {
|
||||
enchantments = new HashMap<>();
|
||||
}
|
||||
|
||||
private EnchantmentContainer(final Map<Enchantment, Integer> enchantments)
|
||||
{
|
||||
private EnchantmentContainer(final Map<Enchantment, Integer> enchantments) {
|
||||
this.enchantments = new HashMap<>(enchantments);
|
||||
}
|
||||
|
||||
@ -57,14 +52,14 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
* @param plugin The {@link ArmoredElytra} instance to use.
|
||||
* @return A new {@link EnchantmentContainer} with the enchantments from the item.
|
||||
*/
|
||||
public static EnchantmentContainer getEnchantmentsOf(final ItemStack is, final ArmoredElytra plugin)
|
||||
{
|
||||
if (is == null)
|
||||
public static EnchantmentContainer getEnchantmentsOf(final ItemStack is, final ArmoredElytra plugin) {
|
||||
if (is == null) {
|
||||
return new EnchantmentContainer(Collections.emptyMap(), plugin);
|
||||
}
|
||||
|
||||
return is.getType() == Material.ENCHANTED_BOOK ?
|
||||
getEnchantmentsFromBook(is, plugin) :
|
||||
getEnchantmentsFromItem(is, plugin);
|
||||
getEnchantmentsFromBook(is, plugin) :
|
||||
getEnchantmentsFromItem(is, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,8 +69,7 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
* @param plugin The {@link ArmoredElytra} instance to use.
|
||||
* @return A new {@link EnchantmentContainer} with the enchantments from the item.
|
||||
*/
|
||||
private static EnchantmentContainer getEnchantmentsFromItem(final ItemStack is, final ArmoredElytra plugin)
|
||||
{
|
||||
private static EnchantmentContainer getEnchantmentsFromItem(final ItemStack is, final ArmoredElytra plugin) {
|
||||
return new EnchantmentContainer(is.getEnchantments(), plugin);
|
||||
}
|
||||
|
||||
@ -86,14 +80,15 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
* @param plugin The {@link ArmoredElytra} instance to use.
|
||||
* @return A new enchantment container with the enchantments from the book.
|
||||
*/
|
||||
private static EnchantmentContainer getEnchantmentsFromBook(final ItemStack is, final ArmoredElytra plugin)
|
||||
{
|
||||
if (!is.hasItemMeta())
|
||||
private static EnchantmentContainer getEnchantmentsFromBook(final ItemStack is, final ArmoredElytra plugin) {
|
||||
if (!is.hasItemMeta()) {
|
||||
return new EnchantmentContainer(new HashMap<>(0), plugin);
|
||||
}
|
||||
|
||||
final EnchantmentStorageMeta meta = (EnchantmentStorageMeta) is.getItemMeta();
|
||||
if (meta == null || !meta.hasStoredEnchants())
|
||||
if (meta == null || !meta.hasStoredEnchants()) {
|
||||
return new EnchantmentContainer(new HashMap<>(0), plugin);
|
||||
}
|
||||
|
||||
return new EnchantmentContainer(meta.getStoredEnchants(), plugin);
|
||||
}
|
||||
@ -105,18 +100,14 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
* @param enchantment The enchantment to get the mutually exclusives of
|
||||
* @return A linked list containing all the mutually exclusive enchantments
|
||||
*/
|
||||
private static List<Enchantment> getMutuallyExclusiveEnchantments(Enchantment enchantment)
|
||||
{
|
||||
private static List<Enchantment> getMutuallyExclusiveEnchantments(Enchantment enchantment) {
|
||||
final List<Enchantment> enchantments = new LinkedList<>();
|
||||
for (final List<Enchantment> mutuallyExclusiveEnchantments :
|
||||
ArmoredElytra.getInstance().getConfigLoader().getMutuallyExclusiveEnchantments())
|
||||
{
|
||||
for (Enchantment mutuallyExclusiveEnchantment : mutuallyExclusiveEnchantments)
|
||||
{
|
||||
if (mutuallyExclusiveEnchantment.equals(enchantment))
|
||||
{
|
||||
ArmoredElytra.getInstance().getConfigLoader().getMutuallyExclusiveEnchantments()) {
|
||||
for (Enchantment mutuallyExclusiveEnchantment : mutuallyExclusiveEnchantments) {
|
||||
if (mutuallyExclusiveEnchantment.equals(enchantment)) {
|
||||
enchantments.addAll(
|
||||
mutuallyExclusiveEnchantments.stream().filter(i -> !i.equals(enchantment)).toList());
|
||||
mutuallyExclusiveEnchantments.stream().filter(i -> !i.equals(enchantment)).toList());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -129,8 +120,7 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
*
|
||||
* @return The total number of enchantments in this container.
|
||||
*/
|
||||
public int getEnchantmentCount()
|
||||
{
|
||||
public int getEnchantmentCount() {
|
||||
return enchantments.size();
|
||||
}
|
||||
|
||||
@ -139,22 +129,22 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
*
|
||||
* @param allowed The names of enchantments (upper case) that are allowed. Any names not in this list are removed.
|
||||
*/
|
||||
public void filter(final Collection<Enchantment> allowed)
|
||||
{
|
||||
if (!enchantments.isEmpty())
|
||||
public void filter(final Collection<Enchantment> allowed) {
|
||||
if (!enchantments.isEmpty()) {
|
||||
enchantments.keySet().retainAll(allowed);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove any entries from the list of enchantments that are mutually exclusive to each other.
|
||||
* <br>First instance of a mutually exclusive enchantment gets priority
|
||||
*/
|
||||
private void filterMutuallyExclusive()
|
||||
{
|
||||
private void filterMutuallyExclusive() {
|
||||
final List<Enchantment> disallowedEnchantments = new LinkedList<>();
|
||||
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet())
|
||||
{
|
||||
if (disallowedEnchantments.contains(entry.getKey())) continue;
|
||||
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
||||
if (disallowedEnchantments.contains(entry.getKey())) {
|
||||
continue;
|
||||
}
|
||||
disallowedEnchantments.addAll(getMutuallyExclusiveEnchantments(entry.getKey()));
|
||||
}
|
||||
disallowedEnchantments.forEach(enchantments.keySet()::remove);
|
||||
@ -165,8 +155,7 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
*
|
||||
* @param is The itemstack to apply the enchantments to.
|
||||
*/
|
||||
public void applyEnchantments(final ItemStack is)
|
||||
{
|
||||
public void applyEnchantments(final ItemStack is) {
|
||||
// Clear enchantments before applying new ones
|
||||
for (Enchantment enchantment : is.getEnchantments().keySet())
|
||||
is.removeEnchantment(enchantment);
|
||||
@ -177,18 +166,17 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
/**
|
||||
* Merges this container with another one.
|
||||
*/
|
||||
public void merge(EnchantmentContainer other)
|
||||
{
|
||||
if (this == other)
|
||||
public void merge(EnchantmentContainer other) {
|
||||
if (this == other) {
|
||||
throw new IllegalArgumentException("EnchantmentContainers cannot be combined with themselves!");
|
||||
}
|
||||
enchantments = merge(enchantments, other.enchantments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of enchantments in this container.
|
||||
*/
|
||||
public int size()
|
||||
{
|
||||
public int size() {
|
||||
return enchantments.size();
|
||||
}
|
||||
|
||||
@ -197,8 +185,7 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
*
|
||||
* @return True if there are exactly 0 enchantments in this container.
|
||||
*/
|
||||
public boolean isEmpty()
|
||||
{
|
||||
public boolean isEmpty() {
|
||||
return enchantments.isEmpty();
|
||||
}
|
||||
|
||||
@ -209,8 +196,7 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
* @param second The second enchantment container. In case of conflicts, this will take precedence.
|
||||
* @return The new map of enchantments.
|
||||
*/
|
||||
public static EnchantmentContainer merge(final EnchantmentContainer first, final EnchantmentContainer second)
|
||||
{
|
||||
public static EnchantmentContainer merge(final EnchantmentContainer first, final EnchantmentContainer second) {
|
||||
return new EnchantmentContainer(merge(first.enchantments, second.enchantments));
|
||||
}
|
||||
|
||||
@ -222,46 +208,46 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
* @return The new map of enchantments.
|
||||
*/
|
||||
private static Map<Enchantment, Integer> merge(final Map<Enchantment, Integer> first,
|
||||
final Map<Enchantment, Integer> second)
|
||||
{
|
||||
if (second == null || second.isEmpty())
|
||||
final Map<Enchantment, Integer> second) {
|
||||
if (second == null || second.isEmpty()) {
|
||||
return first;
|
||||
}
|
||||
|
||||
if (first == null || first.isEmpty())
|
||||
if (first == null || first.isEmpty()) {
|
||||
return second;
|
||||
}
|
||||
|
||||
final List<Enchantment> blackList =
|
||||
second.keySet().stream()
|
||||
.flatMap(ench -> getMutuallyExclusiveEnchantments(ench).stream())
|
||||
.toList();
|
||||
second.keySet().stream()
|
||||
.flatMap(ench -> getMutuallyExclusiveEnchantments(ench).stream())
|
||||
.toList();
|
||||
blackList.forEach(first.keySet()::remove);
|
||||
|
||||
final Map<Enchantment, Integer> combined = new HashMap<>(first);
|
||||
for (Map.Entry<Enchantment, Integer> entry : second.entrySet())
|
||||
{
|
||||
for (Map.Entry<Enchantment, Integer> entry : second.entrySet()) {
|
||||
// Check for enchants with higher level
|
||||
Integer enchantLevel = combined.get(entry.getKey());
|
||||
if (enchantLevel != null)
|
||||
{
|
||||
if (enchantLevel != null) {
|
||||
final int oldLevel = enchantLevel;
|
||||
if (entry.getValue().equals(enchantLevel) && entry.getValue() < entry.getKey().getMaxLevel())
|
||||
if (entry.getValue().equals(enchantLevel) && entry.getValue() < entry.getKey().getMaxLevel()) {
|
||||
enchantLevel = entry.getValue() + 1;
|
||||
else if (entry.getValue() > enchantLevel)
|
||||
} else if (entry.getValue() > enchantLevel) {
|
||||
enchantLevel = entry.getValue();
|
||||
}
|
||||
|
||||
if (enchantLevel != oldLevel)
|
||||
if (enchantLevel != oldLevel) {
|
||||
combined.put(entry.getKey(), enchantLevel);
|
||||
}
|
||||
else
|
||||
}
|
||||
} else {
|
||||
combined.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return combined;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("[");
|
||||
enchantments.forEach((k, v) -> sb.append("\"").append(k).append("\" (").append(v).append("), "));
|
||||
String ret = sb.toString();
|
||||
@ -270,8 +256,7 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Map.Entry<Enchantment, Integer>> iterator()
|
||||
{
|
||||
public Iterator<Map.Entry<Enchantment, Integer>> iterator() {
|
||||
return enchantments.entrySet().iterator();
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package nl.pim16aap2.armoredElytra.util;
|
||||
|
||||
public enum MinecraftVersion
|
||||
{
|
||||
public enum MinecraftVersion {
|
||||
v1_6,
|
||||
v1_7,
|
||||
v1_8,
|
||||
@ -27,8 +26,7 @@ public enum MinecraftVersion
|
||||
|
||||
private final String versionName;
|
||||
|
||||
MinecraftVersion()
|
||||
{
|
||||
MinecraftVersion() {
|
||||
versionName = name().substring(1);
|
||||
}
|
||||
|
||||
@ -38,8 +36,7 @@ public enum MinecraftVersion
|
||||
* @param other The other version to check against.
|
||||
* @return True if this version is newer than the other version.
|
||||
*/
|
||||
public boolean isNewerThan(final MinecraftVersion other)
|
||||
{
|
||||
public boolean isNewerThan(final MinecraftVersion other) {
|
||||
return ordinal() > other.ordinal();
|
||||
}
|
||||
|
||||
@ -49,18 +46,18 @@ public enum MinecraftVersion
|
||||
* @param other The other version to check against.
|
||||
* @return True if this version is older than the other version.
|
||||
*/
|
||||
public boolean isOlderThan(final MinecraftVersion other)
|
||||
{
|
||||
public boolean isOlderThan(final MinecraftVersion other) {
|
||||
return ordinal() < other.ordinal();
|
||||
}
|
||||
|
||||
public static MinecraftVersion get(final String versionName)
|
||||
{
|
||||
if (versionName == null)
|
||||
public static MinecraftVersion get(final String versionName) {
|
||||
if (versionName == null) {
|
||||
return null;
|
||||
}
|
||||
for (final MinecraftVersion mcVersion : MinecraftVersion.values())
|
||||
if (versionName.contains(mcVersion.versionName))
|
||||
if (versionName.contains(mcVersion.versionName)) {
|
||||
return mcVersion;
|
||||
}
|
||||
return MinecraftVersion.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
@ -34,22 +34,22 @@ import java.util.regex.Pattern;
|
||||
*
|
||||
* @author Parker Hawke - 2008Choco
|
||||
*/
|
||||
public final class UpdateChecker
|
||||
{
|
||||
public final class UpdateChecker {
|
||||
public static final IVersionScheme VERSION_SCHEME_DECIMAL = (first, second) ->
|
||||
{
|
||||
String[] firstSplit = splitVersionInfo(first), secondSplit = splitVersionInfo(second);
|
||||
if (firstSplit == null || secondSplit == null)
|
||||
if (firstSplit == null || secondSplit == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < Math.min(firstSplit.length, secondSplit.length); i++)
|
||||
{
|
||||
for (int i = 0; i < Math.min(firstSplit.length, secondSplit.length); i++) {
|
||||
int currentValue = NumberUtils.toInt(firstSplit[i]), newestValue = NumberUtils.toInt(secondSplit[i]);
|
||||
|
||||
if (newestValue > currentValue)
|
||||
if (newestValue > currentValue) {
|
||||
return second;
|
||||
else if (newestValue < currentValue)
|
||||
} else if (newestValue < currentValue) {
|
||||
return first;
|
||||
}
|
||||
}
|
||||
|
||||
return (secondSplit.length > firstSplit.length) ? second : first;
|
||||
@ -67,8 +67,7 @@ public final class UpdateChecker
|
||||
private final int pluginID;
|
||||
private final IVersionScheme versionScheme;
|
||||
|
||||
private UpdateChecker(final ArmoredElytra plugin, final int pluginID, final IVersionScheme versionScheme)
|
||||
{
|
||||
private UpdateChecker(final ArmoredElytra plugin, final int pluginID, final IVersionScheme versionScheme) {
|
||||
this.plugin = plugin;
|
||||
this.pluginID = pluginID;
|
||||
this.versionScheme = versionScheme;
|
||||
@ -80,66 +79,59 @@ public final class UpdateChecker
|
||||
*
|
||||
* @return a future update result
|
||||
*/
|
||||
public CompletableFuture<UpdateResult> requestUpdateCheck()
|
||||
{
|
||||
public CompletableFuture<UpdateResult> requestUpdateCheck() {
|
||||
return CompletableFuture.supplyAsync(
|
||||
() ->
|
||||
{
|
||||
int responseCode;
|
||||
try
|
||||
() ->
|
||||
{
|
||||
URL url = new URL(String.format(UPDATE_URL, pluginID));
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.addRequestProperty("User-Agent", USER_AGENT);
|
||||
int responseCode;
|
||||
try {
|
||||
URL url = new URL(String.format(UPDATE_URL, pluginID));
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.addRequestProperty("User-Agent", USER_AGENT);
|
||||
|
||||
InputStreamReader reader = new InputStreamReader(connection.getInputStream());
|
||||
responseCode = connection.getResponseCode();
|
||||
InputStreamReader reader = new InputStreamReader(connection.getInputStream());
|
||||
responseCode = connection.getResponseCode();
|
||||
|
||||
JsonElement element = new JsonParser().parse(reader);
|
||||
if (!element.isJsonArray())
|
||||
JsonElement element = new JsonParser().parse(reader);
|
||||
if (!element.isJsonArray()) {
|
||||
return new UpdateResult(UpdateReason.INVALID_JSON);
|
||||
}
|
||||
|
||||
reader.close();
|
||||
|
||||
JsonObject versionObject = element.getAsJsonArray().get(0).getAsJsonObject();
|
||||
|
||||
long age = -1;
|
||||
String ageString = versionObject.get("releaseDate").getAsString();
|
||||
try {
|
||||
age = getAge(Long.parseLong(ageString));
|
||||
} catch (NumberFormatException e) {
|
||||
plugin.myLogger(Level.WARNING,
|
||||
"Failed to obtain age of update from ageString: \"" + ageString + "\"");
|
||||
}
|
||||
|
||||
String current = plugin.getDescription().getVersion(), newest = versionObject.get("name")
|
||||
.getAsString();
|
||||
String latest = versionScheme.compareVersions(current, newest);
|
||||
|
||||
if (latest == null) {
|
||||
return new UpdateResult(UpdateReason.UNSUPPORTED_VERSION_SCHEME);
|
||||
} else if (latest.equals(current)) {
|
||||
return new UpdateResult(current.equals(newest) ?
|
||||
UpdateReason.UP_TO_DATE :
|
||||
UpdateReason.UNRELEASED_VERSION, current, age);
|
||||
} else if (latest.equals(newest)) {
|
||||
return new UpdateResult(UpdateReason.NEW_UPDATE, latest, age);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
return new UpdateResult(UpdateReason.COULD_NOT_CONNECT);
|
||||
} catch (JsonSyntaxException e) {
|
||||
return new UpdateResult(UpdateReason.INVALID_JSON);
|
||||
|
||||
reader.close();
|
||||
|
||||
JsonObject versionObject = element.getAsJsonArray().get(0).getAsJsonObject();
|
||||
|
||||
long age = -1;
|
||||
String ageString = versionObject.get("releaseDate").getAsString();
|
||||
try
|
||||
{
|
||||
age = getAge(Long.parseLong(ageString));
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
plugin.myLogger(Level.WARNING,
|
||||
"Failed to obtain age of update from ageString: \"" + ageString + "\"");
|
||||
}
|
||||
|
||||
String current = plugin.getDescription().getVersion(), newest = versionObject.get("name")
|
||||
.getAsString();
|
||||
String latest = versionScheme.compareVersions(current, newest);
|
||||
|
||||
if (latest == null)
|
||||
return new UpdateResult(UpdateReason.UNSUPPORTED_VERSION_SCHEME);
|
||||
else if (latest.equals(current))
|
||||
return new UpdateResult(current.equals(newest) ?
|
||||
UpdateReason.UP_TO_DATE :
|
||||
UpdateReason.UNRELEASED_VERSION, current, age);
|
||||
else if (latest.equals(newest))
|
||||
return new UpdateResult(UpdateReason.NEW_UPDATE, latest, age);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return new UpdateResult(UpdateReason.COULD_NOT_CONNECT);
|
||||
}
|
||||
catch (JsonSyntaxException e)
|
||||
{
|
||||
return new UpdateResult(UpdateReason.INVALID_JSON);
|
||||
}
|
||||
|
||||
return new UpdateResult(responseCode == 401 ?
|
||||
UpdateReason.UNAUTHORIZED_QUERY : UpdateReason.UNKNOWN_ERROR);
|
||||
});
|
||||
return new UpdateResult(responseCode == 401 ?
|
||||
UpdateReason.UNAUTHORIZED_QUERY : UpdateReason.UNKNOWN_ERROR);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,8 +140,7 @@ public final class UpdateChecker
|
||||
* @param updateTime A moment in time to compare the current time to.
|
||||
* @return The difference in seconds between a given time and the current time.
|
||||
*/
|
||||
private long getAge(final long updateTime)
|
||||
{
|
||||
private long getAge(final long updateTime) {
|
||||
long currentTime = Instant.now().getEpochSecond();
|
||||
return currentTime - updateTime;
|
||||
}
|
||||
@ -160,16 +151,15 @@ public final class UpdateChecker
|
||||
*
|
||||
* @return the last update check result. null if none.
|
||||
*/
|
||||
public UpdateResult getLastResult()
|
||||
{
|
||||
public UpdateResult getLastResult() {
|
||||
return lastResult;
|
||||
}
|
||||
|
||||
private static String[] splitVersionInfo(String version)
|
||||
{
|
||||
private static String[] splitVersionInfo(String version) {
|
||||
Matcher matcher = DECIMAL_SCHEME_PATTERN.matcher(version);
|
||||
if (!matcher.find())
|
||||
if (!matcher.find()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return matcher.group().split("\\.");
|
||||
}
|
||||
@ -186,8 +176,7 @@ public final class UpdateChecker
|
||||
* @param versionScheme a custom version scheme parser. Cannot be null
|
||||
* @return the UpdateChecker instance
|
||||
*/
|
||||
public static UpdateChecker init(final ArmoredElytra plugin, final int pluginID, final IVersionScheme versionScheme)
|
||||
{
|
||||
public static UpdateChecker init(final ArmoredElytra plugin, final int pluginID, final IVersionScheme versionScheme) {
|
||||
Preconditions.checkArgument(pluginID > 0, "Plugin ID must be greater than 0");
|
||||
|
||||
return (instance == null) ? instance = new UpdateChecker(plugin, pluginID, versionScheme) : instance;
|
||||
@ -204,8 +193,7 @@ public final class UpdateChecker
|
||||
* value must be greater than 0
|
||||
* @return the UpdateChecker instance
|
||||
*/
|
||||
public static UpdateChecker init(final ArmoredElytra plugin, final int pluginID)
|
||||
{
|
||||
public static UpdateChecker init(final ArmoredElytra plugin, final int pluginID) {
|
||||
return init(plugin, pluginID, VERSION_SCHEME_DECIMAL);
|
||||
}
|
||||
|
||||
@ -215,10 +203,9 @@ public final class UpdateChecker
|
||||
*
|
||||
* @return the UpdateChecker instance
|
||||
*/
|
||||
public static UpdateChecker get()
|
||||
{
|
||||
public static UpdateChecker get() {
|
||||
Preconditions.checkState(instance != null,
|
||||
"Instance has not yet been initialized. Be sure #init() has been invoked");
|
||||
"Instance has not yet been initialized. Be sure #init() has been invoked");
|
||||
return instance;
|
||||
}
|
||||
|
||||
@ -228,8 +215,7 @@ public final class UpdateChecker
|
||||
*
|
||||
* @return true if initialized, false otherwise
|
||||
*/
|
||||
public static boolean isInitialized()
|
||||
{
|
||||
public static boolean isInitialized() {
|
||||
return instance != null;
|
||||
}
|
||||
|
||||
@ -237,8 +223,7 @@ public final class UpdateChecker
|
||||
* A functional interface to compare two version Strings with similar version schemes.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface IVersionScheme
|
||||
{
|
||||
public interface IVersionScheme {
|
||||
|
||||
/**
|
||||
* Compare two versions and return the higher of the two. If null is returned, it is assumed that at least one
|
||||
@ -255,8 +240,7 @@ public final class UpdateChecker
|
||||
/**
|
||||
* A constant reason for the result of {@link UpdateResult}.
|
||||
*/
|
||||
public enum UpdateReason
|
||||
{
|
||||
public enum UpdateReason {
|
||||
|
||||
/**
|
||||
* A new update is available for download.
|
||||
@ -307,8 +291,7 @@ public final class UpdateChecker
|
||||
/**
|
||||
* Represents a result for an update query performed by {@link UpdateChecker#requestUpdateCheck()}.
|
||||
*/
|
||||
public final class UpdateResult
|
||||
{
|
||||
public final class UpdateResult {
|
||||
private final UpdateReason reason;
|
||||
private final String newestVersion;
|
||||
private final long age;
|
||||
@ -317,18 +300,16 @@ public final class UpdateChecker
|
||||
lastResult = this;
|
||||
}
|
||||
|
||||
private UpdateResult(final UpdateReason reason, final String newestVersion, final long age)
|
||||
{
|
||||
private UpdateResult(final UpdateReason reason, final String newestVersion, final long age) {
|
||||
this.reason = reason;
|
||||
this.newestVersion = newestVersion;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
private UpdateResult(final UpdateReason reason)
|
||||
{
|
||||
private UpdateResult(final UpdateReason reason) {
|
||||
Preconditions
|
||||
.checkArgument(reason != UpdateReason.NEW_UPDATE && reason != UpdateReason.UP_TO_DATE,
|
||||
"Reasons that might require updates must also provide the latest version String");
|
||||
.checkArgument(reason != UpdateReason.NEW_UPDATE && reason != UpdateReason.UP_TO_DATE,
|
||||
"Reasons that might require updates must also provide the latest version String");
|
||||
this.reason = reason;
|
||||
newestVersion = plugin.getDescription().getVersion();
|
||||
age = -1;
|
||||
@ -339,8 +320,7 @@ public final class UpdateChecker
|
||||
*
|
||||
* @return the reason
|
||||
*/
|
||||
public UpdateReason getReason()
|
||||
{
|
||||
public UpdateReason getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
@ -349,8 +329,7 @@ public final class UpdateChecker
|
||||
*
|
||||
* @return true if requires update, false otherwise
|
||||
*/
|
||||
public boolean requiresUpdate()
|
||||
{
|
||||
public boolean requiresUpdate() {
|
||||
return reason == UpdateReason.NEW_UPDATE;
|
||||
}
|
||||
|
||||
@ -360,8 +339,7 @@ public final class UpdateChecker
|
||||
*
|
||||
* @return the newest version of the plugin
|
||||
*/
|
||||
public String getNewestVersion()
|
||||
{
|
||||
public String getNewestVersion() {
|
||||
return newestVersion;
|
||||
}
|
||||
|
||||
@ -370,8 +348,7 @@ public final class UpdateChecker
|
||||
*
|
||||
* @return The number of seconds since the last update was released or -1 if unavailable.
|
||||
*/
|
||||
public long getAge()
|
||||
{
|
||||
public long getAge() {
|
||||
return age;
|
||||
}
|
||||
}
|
||||
|
@ -9,77 +9,68 @@ import java.util.logging.Level;
|
||||
/**
|
||||
* @author Pim
|
||||
*/
|
||||
public final class UpdateManager
|
||||
{
|
||||
public final class UpdateManager {
|
||||
private final ArmoredElytra plugin;
|
||||
private boolean checkForUpdates = false;
|
||||
|
||||
private final UpdateChecker updater;
|
||||
private BukkitTask updateRunner = null;
|
||||
|
||||
public UpdateManager(final ArmoredElytra plugin, final int pluginID)
|
||||
{
|
||||
public UpdateManager(final ArmoredElytra plugin, final int pluginID) {
|
||||
this.plugin = plugin;
|
||||
updater = UpdateChecker.init(plugin, pluginID);
|
||||
}
|
||||
|
||||
public void setEnabled(final boolean newCheckForUpdates)
|
||||
{
|
||||
public void setEnabled(final boolean newCheckForUpdates) {
|
||||
checkForUpdates = newCheckForUpdates;
|
||||
initUpdater();
|
||||
}
|
||||
|
||||
public String getNewestVersion()
|
||||
{
|
||||
if (!checkForUpdates || updater.getLastResult() == null)
|
||||
public String getNewestVersion() {
|
||||
if (!checkForUpdates || updater.getLastResult() == null) {
|
||||
return null;
|
||||
}
|
||||
return updater.getLastResult().getNewestVersion();
|
||||
}
|
||||
|
||||
public boolean updateAvailable()
|
||||
{
|
||||
public boolean updateAvailable() {
|
||||
// Updates disabled, so no new updates available by definition.
|
||||
if (!checkForUpdates || updater.getLastResult() == null)
|
||||
if (!checkForUpdates || updater.getLastResult() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return updater.getLastResult().requiresUpdate();
|
||||
}
|
||||
|
||||
public void checkForUpdates()
|
||||
{
|
||||
public void checkForUpdates() {
|
||||
updater.requestUpdateCheck().whenComplete(
|
||||
(result, throwable) ->
|
||||
{
|
||||
boolean updateAvailable = updateAvailable();
|
||||
if (updateAvailable)
|
||||
plugin.myLogger(Level.INFO,
|
||||
"A new update is available: " + plugin.getUpdateManager().getNewestVersion());
|
||||
});
|
||||
(result, throwable) ->
|
||||
{
|
||||
boolean updateAvailable = updateAvailable();
|
||||
if (updateAvailable) {
|
||||
plugin.myLogger(Level.INFO,
|
||||
"A new update is available: " + plugin.getUpdateManager().getNewestVersion());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initUpdater()
|
||||
{
|
||||
if (checkForUpdates)
|
||||
{
|
||||
private void initUpdater() {
|
||||
if (checkForUpdates) {
|
||||
// Run the UpdateChecker regularly.
|
||||
if (updateRunner == null)
|
||||
updateRunner = new BukkitRunnable()
|
||||
{
|
||||
if (updateRunner == null) {
|
||||
updateRunner = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
public void run() {
|
||||
checkForUpdates();
|
||||
}
|
||||
// Run immediately, then every 12 hours.
|
||||
}.runTaskTimer(plugin, 0L, 864000L);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
} else {
|
||||
plugin.myLogger(Level.INFO,
|
||||
"Plugin update checking not enabled! You will not receive any messages about new updates " +
|
||||
"for this plugin. Please consider turning this on in the config.");
|
||||
if (updateRunner != null)
|
||||
{
|
||||
"Plugin update checking not enabled! You will not receive any messages about new updates " +
|
||||
"for this plugin. Please consider turning this on in the config.");
|
||||
if (updateRunner != null) {
|
||||
updateRunner.cancel();
|
||||
updateRunner = null;
|
||||
}
|
||||
|
@ -12,102 +12,75 @@ import java.io.StringWriter;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class Util
|
||||
{
|
||||
public static String errorToString(Error e)
|
||||
{
|
||||
public class Util {
|
||||
public static String errorToString(Error e) {
|
||||
StringWriter sw = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(sw));
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
public static String exceptionToString(Exception e)
|
||||
{
|
||||
public static String exceptionToString(Exception e) {
|
||||
StringWriter sw = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(sw));
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
// Check if an item is broken or not.
|
||||
public static boolean isBroken(ItemStack item)
|
||||
{
|
||||
public static boolean isBroken(ItemStack item) {
|
||||
return item.getDurability() >= item.getType().getMaxDurability();
|
||||
}
|
||||
|
||||
// Get the armor tier from a chest plate.
|
||||
public static ArmorTier armorToTier(ItemStack itemStack)
|
||||
{
|
||||
public static ArmorTier armorToTier(ItemStack itemStack) {
|
||||
return armorToTier(itemStack.getType());
|
||||
}
|
||||
|
||||
// Get the armor tier from a chest plate.
|
||||
public static ArmorTier armorToTier(Material mat)
|
||||
{
|
||||
public static ArmorTier armorToTier(Material mat) {
|
||||
ArmorTier ret = ArmorTier.NONE;
|
||||
XMaterial xmat = XMaterial.matchXMaterial(mat);
|
||||
|
||||
switch (xmat)
|
||||
{
|
||||
case LEATHER_CHESTPLATE:
|
||||
ret = ArmorTier.LEATHER;
|
||||
break;
|
||||
case GOLDEN_CHESTPLATE:
|
||||
ret = ArmorTier.GOLD;
|
||||
break;
|
||||
case CHAINMAIL_CHESTPLATE:
|
||||
ret = ArmorTier.CHAIN;
|
||||
break;
|
||||
case IRON_CHESTPLATE:
|
||||
ret = ArmorTier.IRON;
|
||||
break;
|
||||
case DIAMOND_CHESTPLATE:
|
||||
ret = ArmorTier.DIAMOND;
|
||||
break;
|
||||
case NETHERITE_CHESTPLATE:
|
||||
ret = ArmorTier.NETHERITE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch (xmat) {
|
||||
case LEATHER_CHESTPLATE -> ret = ArmorTier.LEATHER;
|
||||
case GOLDEN_CHESTPLATE -> ret = ArmorTier.GOLD;
|
||||
case CHAINMAIL_CHESTPLATE -> ret = ArmorTier.CHAIN;
|
||||
case IRON_CHESTPLATE -> ret = ArmorTier.IRON;
|
||||
case DIAMOND_CHESTPLATE -> ret = ArmorTier.DIAMOND;
|
||||
case NETHERITE_CHESTPLATE -> ret = ArmorTier.NETHERITE;
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static boolean isChestPlate(ItemStack itemStack)
|
||||
{
|
||||
public static boolean isChestPlate(ItemStack itemStack) {
|
||||
return isChestPlate(itemStack.getType());
|
||||
}
|
||||
|
||||
// Check if mat is a chest plate.
|
||||
public static boolean isChestPlate(Material mat)
|
||||
{
|
||||
try
|
||||
{
|
||||
public static boolean isChestPlate(Material mat) {
|
||||
try {
|
||||
XMaterial xmat = XMaterial.matchXMaterial(mat);
|
||||
|
||||
return xmat == XMaterial.LEATHER_CHESTPLATE || xmat == XMaterial.GOLDEN_CHESTPLATE ||
|
||||
xmat == XMaterial.CHAINMAIL_CHESTPLATE || xmat == XMaterial.IRON_CHESTPLATE ||
|
||||
xmat == XMaterial.DIAMOND_CHESTPLATE || xmat == XMaterial.NETHERITE_CHESTPLATE;
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
xmat == XMaterial.CHAINMAIL_CHESTPLATE || xmat == XMaterial.IRON_CHESTPLATE ||
|
||||
xmat == XMaterial.DIAMOND_CHESTPLATE || xmat == XMaterial.NETHERITE_CHESTPLATE;
|
||||
} catch (IllegalArgumentException e) {
|
||||
// No need to handle this, this is just XMaterial complaining the material doesn't exist.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static String snakeToCamelCase(String input)
|
||||
{
|
||||
public static String snakeToCamelCase(String input) {
|
||||
final char[] arr = input.toLowerCase(Locale.US).toCharArray();
|
||||
|
||||
int skipped = 0;
|
||||
boolean capitalize = false;
|
||||
|
||||
for (int idx = 0; idx < arr.length; ++idx)
|
||||
{
|
||||
for (int idx = 0; idx < arr.length; ++idx) {
|
||||
char current = arr[idx];
|
||||
|
||||
if (current == '_')
|
||||
{
|
||||
if (current == '_') {
|
||||
++skipped;
|
||||
capitalize = true;
|
||||
continue;
|
||||
@ -115,10 +88,10 @@ public class Util
|
||||
|
||||
final int targetIdx = idx - skipped;
|
||||
|
||||
if (capitalize)
|
||||
{
|
||||
if (targetIdx > 0)
|
||||
if (capitalize) {
|
||||
if (targetIdx > 0) {
|
||||
current = Character.toUpperCase(current);
|
||||
}
|
||||
capitalize = false;
|
||||
}
|
||||
|
||||
@ -131,30 +104,34 @@ public class Util
|
||||
}
|
||||
|
||||
// Function that returns which/how many protection enchantments there are.
|
||||
public static int getProtectionEnchantmentsVal(Map<Enchantment, Integer> enchantments)
|
||||
{
|
||||
public static int getProtectionEnchantmentsVal(Map<Enchantment, Integer> enchantments) {
|
||||
int ret = 0;
|
||||
if (enchantments.containsKey(Enchantment.PROTECTION_ENVIRONMENTAL))
|
||||
if (enchantments.containsKey(Enchantment.PROTECTION_ENVIRONMENTAL)) {
|
||||
ret += 1;
|
||||
if (enchantments.containsKey(Enchantment.PROTECTION_EXPLOSIONS))
|
||||
}
|
||||
if (enchantments.containsKey(Enchantment.PROTECTION_EXPLOSIONS)) {
|
||||
ret += 2;
|
||||
if (enchantments.containsKey(Enchantment.PROTECTION_FALL))
|
||||
}
|
||||
if (enchantments.containsKey(Enchantment.PROTECTION_FALL)) {
|
||||
ret += 4;
|
||||
if (enchantments.containsKey(Enchantment.PROTECTION_FIRE))
|
||||
}
|
||||
if (enchantments.containsKey(Enchantment.PROTECTION_FIRE)) {
|
||||
ret += 8;
|
||||
if (enchantments.containsKey(Enchantment.PROTECTION_PROJECTILE))
|
||||
}
|
||||
if (enchantments.containsKey(Enchantment.PROTECTION_PROJECTILE)) {
|
||||
ret += 16;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void moveChestplateToInventory(Player player)
|
||||
{
|
||||
public static void moveChestplateToInventory(Player player) {
|
||||
final PlayerInventory inventory = player.getInventory();
|
||||
inventory.addItem(inventory.getChestplate());
|
||||
|
||||
final @Nullable ItemStack chestplate = inventory.getChestplate();
|
||||
if (chestplate != null)
|
||||
if (chestplate != null) {
|
||||
chestplate.setAmount(0);
|
||||
}
|
||||
|
||||
player.updateInventory();
|
||||
}
|
||||
@ -167,8 +144,7 @@ public class Util
|
||||
* @param max The upper bound limit.
|
||||
* @return The value if it is bigger than min and larger than max, otherwise either min or max.
|
||||
*/
|
||||
public static int between(int val, int min, int max)
|
||||
{
|
||||
public static int between(int val, int min, int max) {
|
||||
return Math.max(min, Math.min(max, val));
|
||||
}
|
||||
}
|
||||
|
@ -65,8 +65,7 @@ import java.util.regex.Pattern;
|
||||
* @see Material
|
||||
* @see ItemStack
|
||||
*/
|
||||
public enum XMaterial
|
||||
{
|
||||
public enum XMaterial {
|
||||
CHAINMAIL_CHESTPLATE,
|
||||
DIAMOND_CHESTPLATE,
|
||||
GOLDEN_CHESTPLATE("GOLD_CHESTPLATE"),
|
||||
@ -95,11 +94,11 @@ public enum XMaterial
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private static final ImmutableSet<String> DAMAGEABLE = ImmutableSet.of(
|
||||
"HELMET", "CHESTPLATE", "LEGGINGS", "BOOTS",
|
||||
"SWORD", "AXE", "PICKAXE", "SHOVEL", "HOE",
|
||||
"ELYTRA", "TRIDENT", "HORSE_ARMOR", "BARDING",
|
||||
"SHEARS", "FLINT_AND_STEEL", "BOW", "FISHING_ROD",
|
||||
"CARROT_ON_A_STICK", "CARROT_STICK", "SPADE", "SHIELD"
|
||||
"HELMET", "CHESTPLATE", "LEGGINGS", "BOOTS",
|
||||
"SWORD", "AXE", "PICKAXE", "SHOVEL", "HOE",
|
||||
"ELYTRA", "TRIDENT", "HORSE_ARMOR", "BARDING",
|
||||
"SHEARS", "FLINT_AND_STEEL", "BOW", "FISHING_ROD",
|
||||
"CARROT_ON_A_STICK", "CARROT_STICK", "SPADE", "SHIELD"
|
||||
);
|
||||
|
||||
/*
|
||||
@ -124,10 +123,10 @@ public enum XMaterial
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private static final Cache<String, XMaterial> NAME_CACHE
|
||||
= CacheBuilder.newBuilder()
|
||||
.softValues()
|
||||
.expireAfterAccess(15, TimeUnit.MINUTES)
|
||||
.build();
|
||||
= CacheBuilder.newBuilder()
|
||||
.softValues()
|
||||
.expireAfterAccess(15, TimeUnit.MINUTES)
|
||||
.build();
|
||||
/**
|
||||
* Guava (Google Core Libraries for Java)'s cache for performance and timed caches. For XMaterials that are already
|
||||
* parsed once.
|
||||
@ -135,11 +134,11 @@ public enum XMaterial
|
||||
* @since 3.0.0
|
||||
*/
|
||||
private static final Cache<XMaterial, Optional<Material>> PARSED_CACHE
|
||||
= CacheBuilder.newBuilder()
|
||||
.softValues()
|
||||
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||
.concurrencyLevel(Runtime.getRuntime().availableProcessors())
|
||||
.build();
|
||||
= CacheBuilder.newBuilder()
|
||||
.softValues()
|
||||
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||
.concurrencyLevel(Runtime.getRuntime().availableProcessors())
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Pre-compiled RegEx pattern. Include both replacements to avoid recreating string multiple times with multiple
|
||||
@ -174,19 +173,16 @@ public enum XMaterial
|
||||
*/
|
||||
private final String[] legacy;
|
||||
|
||||
XMaterial(int data, String... legacy)
|
||||
{
|
||||
XMaterial(int data, String... legacy) {
|
||||
this.data = (byte) data;
|
||||
this.legacy = legacy;
|
||||
}
|
||||
|
||||
XMaterial()
|
||||
{
|
||||
XMaterial() {
|
||||
this(0);
|
||||
}
|
||||
|
||||
XMaterial(String... legacy)
|
||||
{
|
||||
XMaterial(String... legacy) {
|
||||
this(0, legacy);
|
||||
}
|
||||
|
||||
@ -199,13 +195,11 @@ public enum XMaterial
|
||||
* </blockquote>
|
||||
*
|
||||
* @return true if 1.13 or higher.
|
||||
*
|
||||
* @see #getVersion()
|
||||
* @see #supports(int)
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static boolean isNewVersion()
|
||||
{
|
||||
public static boolean isNewVersion() {
|
||||
return ISFLAT;
|
||||
}
|
||||
|
||||
@ -222,8 +216,7 @@ public enum XMaterial
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public static boolean isOneEight()
|
||||
{
|
||||
public static boolean isOneEight() {
|
||||
return !supports(9);
|
||||
}
|
||||
|
||||
@ -231,12 +224,10 @@ public enum XMaterial
|
||||
* The current version of the server.
|
||||
*
|
||||
* @return the current server version or 0.0 if unknown.
|
||||
*
|
||||
* @see #isNewVersion()
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public static double getVersion()
|
||||
{
|
||||
public static double getVersion() {
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
@ -248,18 +239,16 @@ public enum XMaterial
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Nullable
|
||||
private static XMaterial requestOldXMaterial(@Nonnull String name, byte data)
|
||||
{
|
||||
private static XMaterial requestOldXMaterial(@Nonnull String name, byte data) {
|
||||
String holder = name + data;
|
||||
XMaterial cache = NAME_CACHE.getIfPresent(holder);
|
||||
if (cache != null)
|
||||
if (cache != null) {
|
||||
return cache;
|
||||
}
|
||||
|
||||
for (XMaterial material : VALUES)
|
||||
{
|
||||
for (XMaterial material : VALUES) {
|
||||
// Not using material.name().equals(name) check is intended.
|
||||
if ((data == -1 || data == material.data) && material.anyMatchLegacy(name))
|
||||
{
|
||||
if ((data == -1 || data == material.data) && material.anyMatchLegacy(name)) {
|
||||
NAME_CACHE.put(holder, material);
|
||||
return material;
|
||||
}
|
||||
@ -277,17 +266,16 @@ public enum XMaterial
|
||||
*
|
||||
* @param name name of the material.
|
||||
* @return true if XMaterial enum has this material.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static boolean contains(@Nonnull String name)
|
||||
{
|
||||
public static boolean contains(@Nonnull String name) {
|
||||
Validate.notEmpty(name, "Cannot check for null or empty material name");
|
||||
name = format(name);
|
||||
|
||||
for (XMaterial materials : VALUES)
|
||||
if (materials.name().equals(name))
|
||||
if (materials.name().equals(name)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -298,12 +286,12 @@ public enum XMaterial
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Nonnull
|
||||
public static Optional<XMaterial> matchXMaterial(@Nonnull String name)
|
||||
{
|
||||
public static Optional<XMaterial> matchXMaterial(@Nonnull String name) {
|
||||
Validate.notEmpty(name, "Cannot match a material with null or empty material name");
|
||||
Optional<XMaterial> oldMatch = matchXMaterialWithData(name);
|
||||
if (oldMatch.isPresent())
|
||||
if (oldMatch.isPresent()) {
|
||||
return oldMatch;
|
||||
}
|
||||
return matchDefinedXMaterial(format(name), (byte) -1);
|
||||
}
|
||||
|
||||
@ -319,17 +307,15 @@ public enum XMaterial
|
||||
*
|
||||
* @param name the material string that consists of the material name, data and separator character.
|
||||
* @return the parsed XMaterial.
|
||||
*
|
||||
* @see #matchXMaterial(String)
|
||||
* @since 3.0.0
|
||||
*/
|
||||
private static Optional<XMaterial> matchXMaterialWithData(String name)
|
||||
{
|
||||
for (char separator : new char[]{',', ':'})
|
||||
{
|
||||
private static Optional<XMaterial> matchXMaterialWithData(String name) {
|
||||
for (char separator : new char[]{',', ':'}) {
|
||||
int index = name.indexOf(separator);
|
||||
if (index == -1)
|
||||
if (index == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String mat = format(name.substring(0, index));
|
||||
byte data = Byte.parseByte(StringUtils.deleteWhitespace(name.substring(index + 1)));
|
||||
@ -348,11 +334,10 @@ public enum XMaterial
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Nonnull
|
||||
public static XMaterial matchXMaterial(@Nonnull Material material)
|
||||
{
|
||||
public static XMaterial matchXMaterial(@Nonnull Material material) {
|
||||
Objects.requireNonNull(material, "Cannot match null material");
|
||||
return matchDefinedXMaterial(material.name(), (byte) -1)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Unsupported Material With No Bytes: " + material.name()));
|
||||
.orElseThrow(() -> new IllegalArgumentException("Unsupported Material With No Bytes: " + material.name()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -360,21 +345,19 @@ public enum XMaterial
|
||||
*
|
||||
* @param item the ItemStack to match.
|
||||
* @return an XMaterial if matched any.
|
||||
*
|
||||
* @throws IllegalArgumentException may be thrown as an unexpected exception.
|
||||
* @see #matchDefinedXMaterial(String, byte)
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Nonnull
|
||||
@SuppressWarnings("deprecation")
|
||||
public static XMaterial matchXMaterial(@Nonnull ItemStack item)
|
||||
{
|
||||
public static XMaterial matchXMaterial(@Nonnull ItemStack item) {
|
||||
Objects.requireNonNull(item, "Cannot match null ItemStack");
|
||||
String material = item.getType().name();
|
||||
byte data = (byte) (ISFLAT || isDamageable(material) ? 0 : item.getDurability());
|
||||
|
||||
return matchDefinedXMaterial(material, data)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Unsupported Material: " + material + " (" + data + ')'));
|
||||
.orElseThrow(() -> new IllegalArgumentException("Unsupported Material: " + material + " (" + data + ')'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -384,31 +367,27 @@ public enum XMaterial
|
||||
* @param name the formatted name of the material.
|
||||
* @param data the data value of the material.
|
||||
* @return an XMaterial (with the same data value if specified)
|
||||
*
|
||||
* @see #matchXMaterial(Material)
|
||||
* @see #matchXMaterial(int, byte)
|
||||
* @see #matchXMaterial(ItemStack)
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@Nonnull
|
||||
private static Optional<XMaterial> matchDefinedXMaterial(@Nonnull String name, byte data)
|
||||
{
|
||||
private static Optional<XMaterial> matchDefinedXMaterial(@Nonnull String name, byte data) {
|
||||
boolean duplicated = isDuplicated(name);
|
||||
|
||||
// Do basic number and boolean checks before accessing more complex enum stuff.
|
||||
// Maybe we can simplify (ISFLAT || !duplicated) with the (!ISFLAT && duplicated)
|
||||
// under it to save a few nanoseconds?
|
||||
// if (!Boolean.valueOf(Boolean.getBoolean(Boolean.TRUE.toString())).equals(Boolean.FALSE.booleanValue()))
|
||||
// return null;
|
||||
if (data <= 0 && !duplicated)
|
||||
{
|
||||
if (data <= 0 && !duplicated) {
|
||||
// Apparently the transform method is more efficient than toJavaUtil()
|
||||
// toJavaUtil isn't even supported in older versions.
|
||||
Optional<XMaterial> xMat =
|
||||
Enums.getIfPresent(XMaterial.class, name).transform(Optional::of).or(Optional.empty());
|
||||
Enums.getIfPresent(XMaterial.class, name).transform(Optional::of).or(Optional.empty());
|
||||
|
||||
if (xMat.isPresent())
|
||||
if (xMat.isPresent()) {
|
||||
return xMat;
|
||||
}
|
||||
}
|
||||
|
||||
// XMaterial Paradox (Duplication Check)
|
||||
@ -416,11 +395,11 @@ public enum XMaterial
|
||||
// going around the Singular Form and the Plural Form materials. A waste of brain cells and a waste of time.
|
||||
// This solution works just fine anyway.
|
||||
XMaterial xMat = requestOldXMaterial(name, data);
|
||||
if (xMat == null)
|
||||
if (xMat == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (!ISFLAT && duplicated && xMat.name().charAt(xMat.name().length() - 1) == 'S')
|
||||
{
|
||||
if (!ISFLAT && duplicated && xMat.name().charAt(xMat.name().length() - 1) == 'S') {
|
||||
// A solution for XMaterial Paradox.
|
||||
// Manually parses the duplicated materials to find the exact material based on the server version.
|
||||
// If ends with "S" -> Plural Form Material
|
||||
@ -438,12 +417,10 @@ public enum XMaterial
|
||||
*
|
||||
* @param name the name of the material to check.
|
||||
* @return true if there's a duplicated material for this material, otherwise false.
|
||||
*
|
||||
* @see #isDuplicated()
|
||||
* @since 2.0.0
|
||||
*/
|
||||
private static boolean isDuplicated(@Nonnull String name)
|
||||
{
|
||||
private static boolean isDuplicated(@Nonnull String name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -454,18 +431,20 @@ public enum XMaterial
|
||||
* @param id the ID (Magic value) of the material.
|
||||
* @param data the data value of the material.
|
||||
* @return a parsed XMaterial with the same ID and data value.
|
||||
*
|
||||
* @see #matchXMaterial(ItemStack)
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Nonnull
|
||||
public static Optional<XMaterial> matchXMaterial(int id, byte data)
|
||||
{
|
||||
if (id < 0 || data < 0) return Optional.empty();
|
||||
public static Optional<XMaterial> matchXMaterial(int id, byte data) {
|
||||
if (id < 0 || data < 0) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
// Looping through Material.values() will take longer.
|
||||
for (XMaterial materials : VALUES)
|
||||
if (materials.data == data && materials.getId() == id) return Optional.of(materials);
|
||||
if (materials.data == data && materials.getId() == id) {
|
||||
return Optional.of(materials);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@ -475,14 +454,12 @@ public enum XMaterial
|
||||
*
|
||||
* @param name the material name to modify.
|
||||
* @return a Material enum name.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Nonnull
|
||||
private static String format(@Nonnull String name)
|
||||
{
|
||||
private static String format(@Nonnull String name) {
|
||||
return FORMAT_PATTERN.matcher(
|
||||
name.trim().replace('-', '_').replace(' ', '_')).replaceAll("").toUpperCase(Locale.ENGLISH);
|
||||
name.trim().replace('-', '_').replace(' ', '_')).replaceAll("").toUpperCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -490,11 +467,9 @@ public enum XMaterial
|
||||
*
|
||||
* @param version the major version to be checked. "1." is ignored. E.g. 1.12 = 12 | 1.9 = 9
|
||||
* @return true of the version is equal or higher than the current version.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public static boolean supports(int version)
|
||||
{
|
||||
public static boolean supports(int version) {
|
||||
return VERSION >= version;
|
||||
}
|
||||
|
||||
@ -502,13 +477,11 @@ public enum XMaterial
|
||||
* Converts the enum names to a more friendly and readable string.
|
||||
*
|
||||
* @return a formatted string.
|
||||
*
|
||||
* @see #toWord(String)
|
||||
* @since 2.1.0
|
||||
*/
|
||||
@Nonnull
|
||||
public static String toWord(@Nonnull Material material)
|
||||
{
|
||||
public static String toWord(@Nonnull Material material) {
|
||||
Objects.requireNonNull(material, "Cannot translate a null material to a word");
|
||||
return toWord(material.name());
|
||||
}
|
||||
@ -525,12 +498,10 @@ public enum XMaterial
|
||||
*
|
||||
* @param name the name of the enum.
|
||||
* @return a cleaned more readable enum name.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
@Nonnull
|
||||
private static String toWord(@Nonnull String name)
|
||||
{
|
||||
private static String toWord(@Nonnull String name) {
|
||||
return WordUtils.capitalize(name.replace('_', ' ').toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
@ -540,20 +511,17 @@ public enum XMaterial
|
||||
* @param version Supports {@link Bukkit#getVersion()}, {@link Bukkit#getBukkitVersion()} and normal formats such as
|
||||
* "1.14"
|
||||
* @return the exact major version.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Nonnull
|
||||
public static String getMajorVersion(@Nonnull String version)
|
||||
{
|
||||
public static String getMajorVersion(@Nonnull String version) {
|
||||
Validate.notEmpty(version, "Cannot get major Minecraft version from null or empty string");
|
||||
|
||||
// getVersion()
|
||||
int index = version.lastIndexOf("MC:");
|
||||
if (index != -1)
|
||||
if (index != -1) {
|
||||
version = version.substring(index + 4, version.length() - 1);
|
||||
else if (version.endsWith("SNAPSHOT"))
|
||||
{
|
||||
} else if (version.endsWith("SNAPSHOT")) {
|
||||
// getBukkitVersion()
|
||||
index = version.indexOf('-');
|
||||
version = version.substring(0, index);
|
||||
@ -561,8 +529,9 @@ public enum XMaterial
|
||||
|
||||
// 1.13.2, 1.14.4, etc...
|
||||
int lastDot = version.lastIndexOf('.');
|
||||
if (version.indexOf('.') != lastDot)
|
||||
if (version.indexOf('.') != lastDot) {
|
||||
version = version.substring(0, lastDot);
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
@ -572,16 +541,15 @@ public enum XMaterial
|
||||
*
|
||||
* @param name the name of the material.
|
||||
* @return true of the material can be damaged.
|
||||
*
|
||||
* @see #isDamageable()
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static boolean isDamageable(@Nonnull String name)
|
||||
{
|
||||
public static boolean isDamageable(@Nonnull String name) {
|
||||
Objects.requireNonNull(name, "Material name cannot be null");
|
||||
for (String damageable : DAMAGEABLE)
|
||||
if (name.contains(damageable))
|
||||
if (name.contains(damageable)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -622,38 +590,37 @@ public enum XMaterial
|
||||
* @param material the base material to match other materials with.
|
||||
* @param materials the material names to check base material on.
|
||||
* @return true if one of the given material names is similar to the base material.
|
||||
*
|
||||
* @since 3.1.1
|
||||
*/
|
||||
public static boolean isOneOf(@Nonnull Material material, @Nullable List<String> materials)
|
||||
{
|
||||
if (materials == null || materials.isEmpty())
|
||||
public static boolean isOneOf(@Nonnull Material material, @Nullable List<String> materials) {
|
||||
if (materials == null || materials.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
Objects.requireNonNull(material, "Cannot match materials with a null material");
|
||||
String name = material.name();
|
||||
|
||||
for (String comp : materials)
|
||||
{
|
||||
for (String comp : materials) {
|
||||
comp = comp.toUpperCase();
|
||||
if (comp.startsWith("CONTAINS:"))
|
||||
{
|
||||
if (comp.startsWith("CONTAINS:")) {
|
||||
comp = format(comp.substring(9));
|
||||
if (name.contains(comp))
|
||||
if (name.contains(comp)) {
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (comp.startsWith("REGEX:"))
|
||||
{
|
||||
if (comp.startsWith("REGEX:")) {
|
||||
comp = comp.substring(6);
|
||||
if (name.matches(comp))
|
||||
if (name.matches(comp)) {
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Direct Object Equals
|
||||
Optional<XMaterial> mat = matchXMaterial(comp);
|
||||
if (mat.isPresent() && mat.get().parseMaterial() == material)
|
||||
if (mat.isPresent() && mat.get().parseMaterial() == material) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -662,16 +629,16 @@ public enum XMaterial
|
||||
* Gets the version which this material was added in. If the material doesn't have a version it'll return 0;
|
||||
*
|
||||
* @return the Minecraft version which tihs material was added in.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public int getMaterialVersion()
|
||||
{
|
||||
if (this.legacy.length == 0)
|
||||
public int getMaterialVersion() {
|
||||
if (this.legacy.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
String version = this.legacy[0];
|
||||
if (version.charAt(1) != '.')
|
||||
if (version.charAt(1) != '.') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Integer.parseInt(version.substring(2));
|
||||
}
|
||||
@ -688,13 +655,13 @@ public enum XMaterial
|
||||
*/
|
||||
@Nonnull
|
||||
@SuppressWarnings("deprecation")
|
||||
public ItemStack setType(@Nonnull ItemStack item)
|
||||
{
|
||||
public ItemStack setType(@Nonnull ItemStack item) {
|
||||
Objects.requireNonNull(item, "Cannot set material for null ItemStack");
|
||||
|
||||
item.setType(this.parseMaterial());
|
||||
if (!ISFLAT && !this.isDamageable())
|
||||
if (!ISFLAT && !this.isDamageable()) {
|
||||
item.setDurability(this.data);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -703,15 +670,14 @@ public enum XMaterial
|
||||
*
|
||||
* @param materials the material names to check base material on.
|
||||
* @return true if one of the given material names is similar to the base material.
|
||||
*
|
||||
* @see #isOneOf(Material, List)
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public boolean isOneOf(@Nullable List<String> materials)
|
||||
{
|
||||
public boolean isOneOf(@Nullable List<String> materials) {
|
||||
Material material = this.parseMaterial();
|
||||
if (material == null)
|
||||
if (material == null) {
|
||||
return false;
|
||||
}
|
||||
return isOneOf(material, materials);
|
||||
}
|
||||
|
||||
@ -721,18 +687,18 @@ public enum XMaterial
|
||||
*
|
||||
* @param name the name to check
|
||||
* @return true if it's one of the legacy names.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
private boolean anyMatchLegacy(@Nonnull String name)
|
||||
{
|
||||
for (String legacy : this.legacy)
|
||||
{
|
||||
private boolean anyMatchLegacy(@Nonnull String name) {
|
||||
for (String legacy : this.legacy) {
|
||||
if (legacy.isEmpty())
|
||||
// Left-side suggestion list
|
||||
// Left-side suggestion list
|
||||
{
|
||||
break;
|
||||
if (name.equals(legacy))
|
||||
}
|
||||
if (name.equals(legacy)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -741,13 +707,11 @@ public enum XMaterial
|
||||
* User-friendly readable name for this material In most cases you should be using {@link #name()} instead.
|
||||
*
|
||||
* @return string of this object.
|
||||
*
|
||||
* @see #toWord(String)
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
public String toString() {
|
||||
return toWord(this.name());
|
||||
}
|
||||
|
||||
@ -755,15 +719,14 @@ public enum XMaterial
|
||||
* Gets the ID (Magic value) of the material.
|
||||
*
|
||||
* @return the ID of the material or <b>-1</b> if it's a new block or the material is not supported.
|
||||
*
|
||||
* @see #matchXMaterial(int, byte)
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public int getId()
|
||||
{
|
||||
if (this.data != 0 || (this.legacy.length != 0 && Integer.parseInt(this.legacy[0].substring(2)) >= 13))
|
||||
public int getId() {
|
||||
if (this.data != 0 || (this.legacy.length != 0 && Integer.parseInt(this.legacy[0].substring(2)) >= 13)) {
|
||||
return -1;
|
||||
}
|
||||
Material material = this.parseMaterial();
|
||||
return material == null ? -1 : material.getId();
|
||||
}
|
||||
@ -772,12 +735,10 @@ public enum XMaterial
|
||||
* Checks if the material has any duplicates.
|
||||
*
|
||||
* @return true if there is a duplicated name for this material, otherwise false.
|
||||
*
|
||||
* @see #isDuplicated(String)
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public boolean isDuplicated()
|
||||
{
|
||||
public boolean isDuplicated() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -785,12 +746,10 @@ public enum XMaterial
|
||||
* Checks if the material can be damaged by using it. Names going through this method are not formatted.
|
||||
*
|
||||
* @return true if the item can be damaged (have its durability changed), otherwise false.
|
||||
*
|
||||
* @see #isDamageable(String)
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public boolean isDamageable()
|
||||
{
|
||||
public boolean isDamageable() {
|
||||
return isDamageable(this.name());
|
||||
}
|
||||
|
||||
@ -802,12 +761,10 @@ public enum XMaterial
|
||||
* ItemStack#getDurability()} if not damageable.
|
||||
*
|
||||
* @return data of this material, or 0 if none.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public byte getData()
|
||||
{
|
||||
public byte getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -816,12 +773,10 @@ public enum XMaterial
|
||||
* version {@link #isNewVersion()}, then the first element will indicate which version the material was added in.
|
||||
*
|
||||
* @return a list of legacy material names and the first element as the version the material was added in if new.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Nonnull
|
||||
public String[] getLegacy()
|
||||
{
|
||||
public String[] getLegacy() {
|
||||
return legacy;
|
||||
}
|
||||
|
||||
@ -829,14 +784,12 @@ public enum XMaterial
|
||||
* Parses an item from this XMaterial. Uses data values on older versions.
|
||||
*
|
||||
* @return an ItemStack with the same material (and data value if in older versions.)
|
||||
*
|
||||
* @see #parseItem(boolean)
|
||||
* @see #setType(ItemStack)
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Nullable
|
||||
public ItemStack parseItem()
|
||||
{
|
||||
public ItemStack parseItem() {
|
||||
return parseItem(false);
|
||||
}
|
||||
|
||||
@ -845,17 +798,16 @@ public enum XMaterial
|
||||
*
|
||||
* @param suggest if true {@link #parseMaterial(boolean)} true will be used.
|
||||
* @return an ItemStack with the same material (and data value if in older versions.)
|
||||
*
|
||||
* @see #setType(ItemStack)
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("deprecation")
|
||||
public ItemStack parseItem(boolean suggest)
|
||||
{
|
||||
public ItemStack parseItem(boolean suggest) {
|
||||
Material material = this.parseMaterial(suggest);
|
||||
if (material == null)
|
||||
if (material == null) {
|
||||
return null;
|
||||
}
|
||||
return ISFLAT ? new ItemStack(material) : new ItemStack(material, 1, this.data);
|
||||
}
|
||||
|
||||
@ -863,13 +815,11 @@ public enum XMaterial
|
||||
* Parses the material of this XMaterial.
|
||||
*
|
||||
* @return the material related to this XMaterial based on the server version.
|
||||
*
|
||||
* @see #parseMaterial(boolean)
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Nullable
|
||||
public Material parseMaterial()
|
||||
{
|
||||
public Material parseMaterial() {
|
||||
return parseMaterial(false);
|
||||
}
|
||||
|
||||
@ -879,29 +829,29 @@ public enum XMaterial
|
||||
* @param suggest use a suggested material (from older materials) if the material is added in a later version of
|
||||
* Minecraft.
|
||||
* @return the material related to this XMaterial based on the server version.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@SuppressWarnings("OptionalAssignedToNull")
|
||||
@Nullable
|
||||
public Material parseMaterial(boolean suggest)
|
||||
{
|
||||
public Material parseMaterial(boolean suggest) {
|
||||
Optional<Material> cache = PARSED_CACHE.getIfPresent(this);
|
||||
if (cache != null)
|
||||
if (cache != null) {
|
||||
return cache.orElse(null);
|
||||
}
|
||||
Material mat;
|
||||
|
||||
if (!ISFLAT && this.isDuplicated())
|
||||
if (!ISFLAT && this.isDuplicated()) {
|
||||
mat = requestOldMaterial(suggest);
|
||||
else
|
||||
{
|
||||
} else {
|
||||
mat = Material.getMaterial(this.name());
|
||||
if (mat == null)
|
||||
if (mat == null) {
|
||||
mat = requestOldMaterial(suggest);
|
||||
}
|
||||
}
|
||||
|
||||
if (mat != null)
|
||||
if (mat != null) {
|
||||
PARSED_CACHE.put(this, Optional.ofNullable(mat));
|
||||
}
|
||||
return mat;
|
||||
}
|
||||
|
||||
@ -910,34 +860,34 @@ public enum XMaterial
|
||||
*
|
||||
* @param suggest if true suggested materials will be considered for old versions.
|
||||
* @return a parsed material suitable for the current Minecraft version.
|
||||
*
|
||||
* @see #parseMaterial(boolean)
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Nullable
|
||||
private Material requestOldMaterial(boolean suggest)
|
||||
{
|
||||
for (int i = this.legacy.length - 1; i >= 0; i--)
|
||||
{
|
||||
private Material requestOldMaterial(boolean suggest) {
|
||||
for (int i = this.legacy.length - 1; i >= 0; i--) {
|
||||
String legacy = this.legacy[i];
|
||||
|
||||
// Check if we've reached the end and the last string is our
|
||||
// material version.
|
||||
if (i == 0 && legacy.charAt(1) == '.')
|
||||
if (i == 0 && legacy.charAt(1) == '.') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// According to the suggestion list format, all the other names continuing
|
||||
// from here are considered as a "suggestion"
|
||||
// The empty string is an indicator for suggestion list on the left side.
|
||||
if (legacy.isEmpty())
|
||||
{
|
||||
if (suggest) continue;
|
||||
if (legacy.isEmpty()) {
|
||||
if (suggest) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Material material = Material.getMaterial(legacy);
|
||||
if (material != null)
|
||||
if (material != null) {
|
||||
return material;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -948,15 +898,14 @@ public enum XMaterial
|
||||
* @param item item to check.
|
||||
* @return true if the material is the same as the item's material (and data value if on older versions), otherwise
|
||||
* false.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean isSimilar(@Nonnull ItemStack item)
|
||||
{
|
||||
public boolean isSimilar(@Nonnull ItemStack item) {
|
||||
Objects.requireNonNull(item, "Cannot compare with null ItemStack");
|
||||
if (item.getType() != this.parseMaterial())
|
||||
if (item.getType() != this.parseMaterial()) {
|
||||
return false;
|
||||
}
|
||||
return ISFLAT || this.isDamageable() || item.getDurability() == this.data;
|
||||
}
|
||||
|
||||
@ -964,20 +913,19 @@ public enum XMaterial
|
||||
* Gets the suggested material names that can be used if the material is not supported in the current version.
|
||||
*
|
||||
* @return a list of suggested material names.
|
||||
*
|
||||
* @see #parseMaterial(boolean)
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Nonnull
|
||||
public List<String> getSuggestions()
|
||||
{
|
||||
if (this.legacy.length == 0 || this.legacy[0].charAt(1) != '.')
|
||||
public List<String> getSuggestions() {
|
||||
if (this.legacy.length == 0 || this.legacy[0].charAt(1) != '.') {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<String> suggestions = new ArrayList<>();
|
||||
for (String legacy : this.legacy)
|
||||
{
|
||||
if (legacy.isEmpty())
|
||||
for (String legacy : this.legacy) {
|
||||
if (legacy.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
suggestions.add(legacy);
|
||||
}
|
||||
return suggestions;
|
||||
@ -990,18 +938,18 @@ public enum XMaterial
|
||||
* material later.
|
||||
*
|
||||
* @return true if the material exists in {@link Material} list.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public boolean isSupported()
|
||||
{
|
||||
public boolean isSupported() {
|
||||
int version = this.getMaterialVersion();
|
||||
if (version != 0)
|
||||
if (version != 0) {
|
||||
return supports(version);
|
||||
}
|
||||
|
||||
Material material = Material.getMaterial(this.name());
|
||||
if (material != null)
|
||||
if (material != null) {
|
||||
return true;
|
||||
}
|
||||
return requestOldMaterial(false) != null;
|
||||
}
|
||||
|
||||
@ -1009,12 +957,10 @@ public enum XMaterial
|
||||
* Checks if the material is newly added after the 1.13 Aquatic Update.
|
||||
*
|
||||
* @return true if the material was newly added, otherwise false.
|
||||
*
|
||||
* @see #getMaterialVersion()
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public boolean isFromNewSystem()
|
||||
{
|
||||
public boolean isFromNewSystem() {
|
||||
return this.legacy.length != 0 && Integer.parseInt(this.legacy[0].substring(2)) > 13;
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,7 @@ package nl.pim16aap2.armoredElytra.util.messages;
|
||||
*
|
||||
* @author Pim
|
||||
*/
|
||||
public interface IMessageVariable
|
||||
{
|
||||
public interface IMessageVariable {
|
||||
String VAR_TIER_NAME = "%ARMOR_TIER%";
|
||||
String VAR_TIER_NAME_SHORT = "%ARMOR_TIER_SHORT%";
|
||||
}
|
||||
|
@ -5,8 +5,7 @@ package nl.pim16aap2.armoredElytra.util.messages;
|
||||
*
|
||||
* @author Pim
|
||||
*/
|
||||
public enum Message implements IMessageVariable
|
||||
{
|
||||
public enum Message implements IMessageVariable {
|
||||
EMPTY(),
|
||||
|
||||
TIER_LEATHER(),
|
||||
@ -46,8 +45,7 @@ public enum Message implements IMessageVariable
|
||||
*
|
||||
* @param variableNames The names of the variables in the value that can be replaced.
|
||||
*/
|
||||
Message(final String... variableNames)
|
||||
{
|
||||
Message(final String... variableNames) {
|
||||
this.variableNames = variableNames;
|
||||
}
|
||||
|
||||
@ -58,8 +56,7 @@ public enum Message implements IMessageVariable
|
||||
* @param idx The index of the variable name.
|
||||
* @return The name of the variable at the given position of this message.
|
||||
*/
|
||||
public static String getVariableName(final Message msg, final int idx)
|
||||
{
|
||||
public static String getVariableName(final Message msg, final int idx) {
|
||||
return msg.variableNames[idx];
|
||||
}
|
||||
|
||||
@ -69,8 +66,7 @@ public enum Message implements IMessageVariable
|
||||
* @param msg The message for which to retrieve the variable names.
|
||||
* @return The names of the variables of this message.
|
||||
*/
|
||||
public static String[] getVariableNames(final Message msg)
|
||||
{
|
||||
public static String[] getVariableNames(final Message msg) {
|
||||
return msg.variableNames;
|
||||
}
|
||||
|
||||
@ -80,8 +76,7 @@ public enum Message implements IMessageVariable
|
||||
* @param msg The message to retrieve the variable count for.
|
||||
* @return The number of variables in this message that can be substituted.
|
||||
*/
|
||||
public static int getVariableCount(final Message msg)
|
||||
{
|
||||
public static int getVariableCount(final Message msg) {
|
||||
return msg.variableNames.length;
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ import java.util.jar.JarFile;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Messages
|
||||
{
|
||||
public class Messages {
|
||||
private static final String DEFAULT_FILENAME = "en_US.txt";
|
||||
|
||||
/**
|
||||
@ -43,8 +42,7 @@ public class Messages
|
||||
private static final Pattern matchNewLines = Pattern.compile("\\\\n");
|
||||
private static final Pattern matchColorCodes = Pattern.compile("&((?i)[0-9a-fk-or])");
|
||||
|
||||
public Messages(final ArmoredElytra plugin)
|
||||
{
|
||||
public Messages(final ArmoredElytra plugin) {
|
||||
this.plugin = plugin;
|
||||
writeDefaultFiles(plugin);
|
||||
|
||||
@ -53,10 +51,9 @@ public class Messages
|
||||
|
||||
textFile = Path.of(plugin.getDataFolder().toURI()).resolve(fileName);
|
||||
|
||||
if (!Files.exists(textFile))
|
||||
{
|
||||
if (!Files.exists(textFile)) {
|
||||
plugin.myLogger(Level.WARNING, "Failed to load language file: \"" + textFile +
|
||||
"\": File not found! Using default file (\"" + DEFAULT_FILENAME + "\") instead!");
|
||||
"\": File not found! Using default file (\"" + DEFAULT_FILENAME + "\") instead!");
|
||||
textFile = Path.of(plugin.getDataFolder().toURI()).resolve(DEFAULT_FILENAME);
|
||||
}
|
||||
populateMessageMap();
|
||||
@ -71,31 +68,27 @@ public class Messages
|
||||
* @throws IOException
|
||||
*/
|
||||
private void processFile(final BufferedReader br, final BiConsumer<Message, String> action)
|
||||
throws IOException
|
||||
{
|
||||
throws IOException {
|
||||
String sCurrentLine;
|
||||
|
||||
while ((sCurrentLine = br.readLine()) != null)
|
||||
{
|
||||
while ((sCurrentLine = br.readLine()) != null) {
|
||||
// Ignore comments.
|
||||
if (sCurrentLine.startsWith("#") || sCurrentLine.isEmpty())
|
||||
if (sCurrentLine.startsWith("#") || sCurrentLine.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] parts = sCurrentLine.split("=", 2);
|
||||
try
|
||||
{
|
||||
try {
|
||||
final Message msg = Message.valueOf(matchDots.matcher(parts[0]).replaceAll("_").toUpperCase());
|
||||
final String value = matchNewLines.matcher(matchColorCodes.matcher(parts[1]).replaceAll("\u00A7$1"))
|
||||
.replaceAll("\n");
|
||||
.replaceAll("\n");
|
||||
action.accept(msg, value);
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
} catch (IllegalArgumentException e) {
|
||||
plugin.myLogger(Level.WARNING, "Failed to identify Message corresponding to key: \"" + parts[0] +
|
||||
"\". Its value will be ignored!");
|
||||
"\". Its value will be ignored!");
|
||||
|
||||
System.out.println(
|
||||
"Trying to find enum value of: " + matchDots.matcher(parts[0]).replaceAll("_").toUpperCase());
|
||||
"Trying to find enum value of: " + matchDots.matcher(parts[0]).replaceAll("_").toUpperCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -106,8 +99,7 @@ public class Messages
|
||||
* @param message The {@link Message}.
|
||||
* @param value The value of the message.
|
||||
*/
|
||||
private void addMessage(final Message message, final String value)
|
||||
{
|
||||
private void addMessage(final Message message, final String value) {
|
||||
messageMap.put(message, value);
|
||||
}
|
||||
|
||||
@ -117,13 +109,13 @@ public class Messages
|
||||
* @param message The {@link Message}.
|
||||
* @param value The value of the message.
|
||||
*/
|
||||
private void addBackupMessage(final Message message, final String value)
|
||||
{
|
||||
if (messageMap.containsKey(message))
|
||||
private void addBackupMessage(final Message message, final String value) {
|
||||
if (messageMap.containsKey(message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.myLogger(Level.WARNING,
|
||||
"Could not find translation of key: \"" + message.name() + "\". Using default value instead!");
|
||||
"Could not find translation of key: \"" + message.name() + "\". Using default value instead!");
|
||||
addMessage(message, value);
|
||||
}
|
||||
|
||||
@ -132,43 +124,31 @@ public class Messages
|
||||
* <p>
|
||||
* Missing translations will use their default value.
|
||||
*/
|
||||
private void populateMessageMap()
|
||||
{
|
||||
try (BufferedReader br = Files.newBufferedReader(textFile, StandardCharsets.UTF_8))
|
||||
{
|
||||
private void populateMessageMap() {
|
||||
try (BufferedReader br = Files.newBufferedReader(textFile, StandardCharsets.UTF_8)) {
|
||||
processFile(br, this::addMessage);
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
} catch (FileNotFoundException e) {
|
||||
plugin.myLogger(Level.SEVERE, "Locale file \"" + textFile + "\" does not exist!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
} catch (IOException e) {
|
||||
plugin.myLogger(Level.SEVERE, "Could not read locale file! \"" + textFile + "\"");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
final URL defaultFileUrl = Objects.requireNonNull(getClass().getClassLoader().getResource(DEFAULT_FILENAME));
|
||||
try (BufferedReader br = new BufferedReader(
|
||||
new InputStreamReader(defaultFileUrl.openStream(), StandardCharsets.UTF_8)))
|
||||
{
|
||||
new InputStreamReader(defaultFileUrl.openStream(), StandardCharsets.UTF_8))) {
|
||||
processFile(br, this::addBackupMessage);
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
} catch (FileNotFoundException e) {
|
||||
plugin.myLogger(Level.SEVERE, "Failed to load internal locale file!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
} catch (IOException e) {
|
||||
plugin.myLogger(Level.SEVERE, "Could not read internal locale file!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (final Message msg : Message.values())
|
||||
if (!msg.equals(Message.EMPTY) && !messageMap.containsKey(msg))
|
||||
{
|
||||
if (!msg.equals(Message.EMPTY) && !messageMap.containsKey(msg)) {
|
||||
plugin.myLogger(Level.WARNING, "Could not find translation of key: " + msg.name());
|
||||
messageMap.put(msg, getFailureString(msg.name()));
|
||||
}
|
||||
@ -180,8 +160,7 @@ public class Messages
|
||||
* @param key The key that could not be resolved.
|
||||
* @return The default String to return in case a value could not be found for a given String.
|
||||
*/
|
||||
private String getFailureString(final String key)
|
||||
{
|
||||
private String getFailureString(final String key) {
|
||||
return "Translation for key \"" + key + "\" not found! Contact server admin!";
|
||||
}
|
||||
|
||||
@ -194,22 +173,20 @@ public class Messages
|
||||
* @return The translated message of the provided {@link Message} and substitutes its variables for the provided
|
||||
* values.
|
||||
*/
|
||||
public String getString(final Message msg, final String... values)
|
||||
{
|
||||
if (msg.equals(Message.EMPTY))
|
||||
public String getString(final Message msg, final String... values) {
|
||||
if (msg.equals(Message.EMPTY)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (values.length != Message.getVariableCount(msg))
|
||||
{
|
||||
if (values.length != Message.getVariableCount(msg)) {
|
||||
plugin.myLogger(Level.SEVERE,
|
||||
"Expected " + Message.getVariableCount(msg) + " variables for key " + msg.name() +
|
||||
" but only got " + values.length + ". This is a bug. Please contact pim16aap2!");
|
||||
"Expected " + Message.getVariableCount(msg) + " variables for key " + msg.name() +
|
||||
" but only got " + values.length + ". This is a bug. Please contact pim16aap2!");
|
||||
return getFailureString(msg.name());
|
||||
}
|
||||
|
||||
String value = messageMap.get(msg);
|
||||
if (value != null)
|
||||
{
|
||||
if (value != null) {
|
||||
for (int idx = 0; idx != values.length; ++idx)
|
||||
value = value.replaceAll(Message.getVariableName(msg, idx), values[idx]);
|
||||
return value;
|
||||
@ -219,37 +196,30 @@ public class Messages
|
||||
return getFailureString(msg.name());
|
||||
}
|
||||
|
||||
private static void writeDefaultFiles(ArmoredElytra plugin)
|
||||
{
|
||||
try
|
||||
{
|
||||
private static void writeDefaultFiles(ArmoredElytra plugin) {
|
||||
try {
|
||||
getPackagedLocalizations(plugin).forEach(file -> plugin.saveResource(file, false));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
} catch (IOException e) {
|
||||
plugin.myLogger(Level.SEVERE, "Failed to write default localization files!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> getPackagedLocalizations(ArmoredElytra plugin)
|
||||
throws IOException
|
||||
{
|
||||
throws IOException {
|
||||
final List<String> files = new ArrayList<>();
|
||||
|
||||
final Enumeration<URL> enumeration = plugin.getClass().getClassLoader().getResources("META-INF");
|
||||
while (enumeration.hasMoreElements())
|
||||
{
|
||||
while (enumeration.hasMoreElements()) {
|
||||
final URL url = enumeration.nextElement();
|
||||
final JarURLConnection connection = (JarURLConnection) url.openConnection();
|
||||
try (JarFile jarFile = connection.getJarFile())
|
||||
{
|
||||
try (JarFile jarFile = connection.getJarFile()) {
|
||||
final Enumeration<JarEntry> jarEntries = jarFile.entries();
|
||||
while (jarEntries.hasMoreElements())
|
||||
{
|
||||
while (jarEntries.hasMoreElements()) {
|
||||
final String name = jarEntries.nextElement().getName();
|
||||
if (!name.contains("/") && (name.endsWith(".txt")))
|
||||
if (!name.contains("/") && (name.endsWith(".txt"))) {
|
||||
files.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,11 +3,9 @@ package nl.pim16aap2.armoredElytra.util;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class UtilTest
|
||||
{
|
||||
class UtilTest {
|
||||
@Test
|
||||
void testSnakeToCamelCase()
|
||||
{
|
||||
void testSnakeToCamelCase() {
|
||||
Assertions.assertEquals("testCase", Util.snakeToCamelCase("TeSt_Case"));
|
||||
Assertions.assertEquals("testCase", Util.snakeToCamelCase("____test_case"));
|
||||
Assertions.assertEquals("", Util.snakeToCamelCase("________"));
|
||||
|
Loading…
Reference in New Issue
Block a user