Update NBT system to support recent Paper builds

- Overhauled the way armor values are retrieved so that this plugin is compatible with Paper 178+. This new method should also be a bit more robust against future changes.
- Reformatted the code some.
- Fixed FlyDurabilityHandler. It used to check Player#isFlying. This checks if the player if flying using creative flight, not using an elytra. Player#isGliding actually checks if the player is flying using an elytra.
This commit is contained in:
Pim van der Loos 2020-04-19 12:09:48 +02:00
parent 19ab2cdab1
commit 51854fa150
No known key found for this signature in database
GPG Key ID: C16F020ADAE6D5A8
10 changed files with 495 additions and 422 deletions

24
pom.xml
View File

@ -11,10 +11,14 @@
<id>spigot-repo</id> <id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url> <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository> </repository>
<!-- bStats -->
<repository> <repository>
<id>CodeMC</id> <id>CodeMC</id>
<url>https://repo.codemc.org/repository/maven-public</url> <url>https://repo.codemc.org/repository/maven-public/</url>
</repository> </repository>
<!-- Item-NBT-API-->
<repository> <repository>
<id>jitpack.io</id> <id>jitpack.io</id>
<url>https://jitpack.io</url> <url>https://jitpack.io</url>
@ -22,17 +26,19 @@
</repositories> </repositories>
<dependencies> <dependencies>
<!-- Spigot API (docs) -->
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId> <artifactId>spigot-api</artifactId>
<version>1.14.2-R0.1-SNAPSHOT</version> <version>1.15.1-R0.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- Spigot API + (Craft)Bukkit API + NMS -->
<dependency> <dependency>
<groupId>com.github.tr7zw</groupId> <groupId>org.spigotmc</groupId>
<artifactId>Item-NBT-API</artifactId> <artifactId>spigot</artifactId>
<version>master-SNAPSHOT</version> <version>1.15.1-R0.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
@ -86,10 +92,6 @@
<pattern>org.bstats</pattern> <pattern>org.bstats</pattern>
<shadedPattern>nl.pim16aap2.armoredElytra</shadedPattern> <shadedPattern>nl.pim16aap2.armoredElytra</shadedPattern>
</relocation> </relocation>
<!--<relocation>
<pattern>com.codingforcookies</pattern>
<shadedPattern>nl.pim16aap2.armoredElytra</shadedPattern>
</relocation>-->
</relocations> </relocations>
</configuration> </configuration>
<executions> <executions>
@ -124,7 +126,7 @@
<configuration> <configuration>
<target> <target>
<ant antfile="${basedir}/mover.xml"> <ant antfile="${basedir}/mover.xml">
<target name="copyAll" /> <target name="copyAll"/>
</ant> </ant>
</target> </target>
</configuration> </configuration>

View File

@ -1,19 +1,5 @@
package nl.pim16aap2.armoredElytra; package nl.pim16aap2.armoredElytra;
import java.util.EnumMap;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import nl.pim16aap2.armoredElytra.handlers.CommandHandler; import nl.pim16aap2.armoredElytra.handlers.CommandHandler;
import nl.pim16aap2.armoredElytra.handlers.EventHandlers; import nl.pim16aap2.armoredElytra.handlers.EventHandlers;
import nl.pim16aap2.armoredElytra.handlers.FlyDurabilityHandler; import nl.pim16aap2.armoredElytra.handlers.FlyDurabilityHandler;
@ -25,6 +11,19 @@ import nl.pim16aap2.armoredElytra.util.ArmorTierName;
import nl.pim16aap2.armoredElytra.util.ConfigLoader; import nl.pim16aap2.armoredElytra.util.ConfigLoader;
import nl.pim16aap2.armoredElytra.util.Messages; import nl.pim16aap2.armoredElytra.util.Messages;
import nl.pim16aap2.armoredElytra.util.Update; import nl.pim16aap2.armoredElytra.util.Update;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.EnumMap;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Level;
import java.util.regex.Pattern;
// TODO: Use this for NBT stuff: https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/ // TODO: Use this for NBT stuff: https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/
// TODO: Figure out if the config really does read the list of enchantments accurately. A bug report with a customized config seemed to load the default settings... // TODO: Figure out if the config really does read the list of enchantments accurately. A bug report with a customized config seemed to load the default settings...
@ -33,11 +32,11 @@ import nl.pim16aap2.armoredElytra.util.Update;
public class ArmoredElytra extends JavaPlugin implements Listener public class ArmoredElytra extends JavaPlugin implements Listener
{ {
private NBTEditor nbtEditor; private static ArmoredElytra instance;
private Messages messages; private Messages messages;
private ConfigLoader config; private ConfigLoader config;
// private String leatherName, ironName, goldName, chainName, diamondName; // private String leatherName, ironName, goldName, chainName, diamondName;
private final Map<ArmorTier, ArmorTierName> armorTierNames = new EnumMap(ArmorTier.class); private final Map<ArmorTier, ArmorTierName> armorTierNames = new EnumMap(ArmorTier.class);
private String elytraReceivedMessage; private String elytraReceivedMessage;
private String usageDeniedMessage; private String usageDeniedMessage;
@ -48,6 +47,7 @@ public class ArmoredElytra extends JavaPlugin implements Listener
@Override @Override
public void onEnable() public void onEnable()
{ {
instance = this;
config = new ConfigLoader(this); config = new ConfigLoader(this);
messages = new Messages(this); messages = new Messages(this);
readMessages(); readMessages();
@ -56,14 +56,16 @@ public class ArmoredElytra extends JavaPlugin implements Listener
if (config.checkForUpdates()) if (config.checkForUpdates())
{ {
// Check for updates in a new thread, so the server won't hang when it cannot contact the update servers. // Check for updates in a new thread, so the server won't hang when it cannot contact the update servers.
final Thread thread = new Thread(() -> final Thread thread = new Thread(
() ->
{ {
final ArmoredElytra plugin = getPlugin(); final ArmoredElytra plugin = getPlugin();
final Update update = new Update(278437, plugin); final Update update = new Update(278437, plugin);
final String latestVersion = update.getLatestVersion(); final String latestVersion = update.getLatestVersion();
if (latestVersion == null) if (latestVersion == null)
plugin.myLogger(Level.WARNING, "Encountered problem contacting update servers! Please check manually! The error above does not affect the plugin!"); plugin.myLogger(Level.WARNING,
"Encountered problem contacting update servers! Please check manually! The error above does not affect the plugin!");
else else
{ {
final String thisVersion = plugin.getDescription().getVersion(); final String thisVersion = plugin.getDescription().getVersion();
@ -73,8 +75,11 @@ public class ArmoredElytra extends JavaPlugin implements Listener
if (updateStatus > 0) if (updateStatus > 0)
{ {
// Load the loginHandler to show messages to the user when they join. // Load the loginHandler to show messages to the user when they join.
Bukkit.getPluginManager().registerEvents(new LoginHandler(plugin, "The Armored Elytra plugin is out of date!"), plugin); Bukkit.getPluginManager()
plugin.myLogger(Level.INFO, "Plugin out of date! You are using version " + thisVersion + " but the latest version is version " + latestVersion + "!"); .registerEvents(new LoginHandler(plugin, "The Armored Elytra plugin is out of date!"),
plugin);
plugin.myLogger(Level.INFO, "Plugin out of date! You are using version " + thisVersion +
" but the latest version is version " + latestVersion + "!");
plugin.setUpToDate(false); plugin.setUpToDate(false);
} }
else else
@ -87,29 +92,32 @@ public class ArmoredElytra extends JavaPlugin implements Listener
thread.start(); thread.start();
} }
else else
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."); 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 (config.allowStats()) if (config.allowStats())
{ {
myLogger(Level.INFO, "Enabling stats! Thanks, it really helps!"); myLogger(Level.INFO, "Enabling stats! Thanks, it really helps!");
@SuppressWarnings("unused") @SuppressWarnings("unused") final Metrics metrics = new Metrics(this);
final
Metrics metrics = new Metrics(this);
} }
else else
// Y u do dis? :( // 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!"); 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!");
// Load the files for the correct version of Minecraft. // Load the files for the correct version of Minecraft.
if (compatibleMCVer()) if (compatibleMCVer())
{ {
Bukkit.getPluginManager().registerEvents(new EventHandlers(this, nbtEditor, is1_9), this); Bukkit.getPluginManager().registerEvents(new EventHandlers(this, is1_9), this);
getCommand("ArmoredElytra").setExecutor(new CommandHandler(this, nbtEditor)); getCommand("ArmoredElytra").setExecutor(new CommandHandler(this));
} }
else else
{ {
Bukkit.getPluginManager().registerEvents(new LoginHandler(this, "The Armored Elytra plugin failed to start correctly! Please send the startup log to pim16aap2!"), this); Bukkit.getPluginManager().registerEvents(new LoginHandler(this,
myLogger(Level.WARNING, "Plugin failed to load! Either your version isn't supported or something went horribly wrong! Please contact pim16aap2!"); "The Armored Elytra plugin failed to start correctly! Please send the startup log to pim16aap2!"),
this);
myLogger(Level.WARNING,
"Plugin failed to load! Either your version isn't supported or something went horribly wrong! Please contact pim16aap2!");
return; return;
} }
@ -119,11 +127,11 @@ public class ArmoredElytra extends JavaPlugin implements Listener
// Check if the user wants to disable durability penalty for flying with an armored elytra. // Check if the user wants to disable durability penalty for flying with an armored elytra.
if (config.noFlightDurability()) if (config.noFlightDurability())
{ {
Bukkit.getPluginManager().registerEvents(new FlyDurabilityHandler(nbtEditor), this); Bukkit.getPluginManager().registerEvents(new FlyDurabilityHandler(), this);
myLogger(Level.INFO, "Durability penalty for flying enabled!"); myLogger(Level.INFO, "Durability penalty for flying disabled!");
} }
else else
myLogger(Level.INFO, "Durability penalty for flying disabled!"); myLogger(Level.INFO, "Durability penalty for flying enabled!");
// Log all allowed enchantments. // Log all allowed enchantments.
myLogger(Level.INFO, ("Allowed enchantments:")); myLogger(Level.INFO, ("Allowed enchantments:"));
@ -133,7 +141,7 @@ public class ArmoredElytra extends JavaPlugin implements Listener
else else
{ {
myLogger(Level.WARNING, "Plugin in uninstall mode!"); myLogger(Level.WARNING, "Plugin in uninstall mode!");
Bukkit.getPluginManager().registerEvents(new Uninstaller(this, nbtEditor), this); Bukkit.getPluginManager().registerEvents(new Uninstaller(this), this);
} }
} }
@ -167,19 +175,22 @@ public class ArmoredElytra extends JavaPlugin implements Listener
getColorCodedStringFromConfig("TIER.SHORT.Diamond"))); getColorCodedStringFromConfig("TIER.SHORT.Diamond")));
// Change the string to null if it says "NONE". // Change the string to null if it says "NONE".
usageDeniedMessage = (Objects.equals(usageDeniedMessage, new String("NONE")) ? null : usageDeniedMessage ); usageDeniedMessage = (Objects.equals(usageDeniedMessage, new String("NONE")) ? null : usageDeniedMessage);
elytraReceivedMessage = (Objects.equals(elytraReceivedMessage, new String("NONE")) ? null : elytraReceivedMessage); elytraReceivedMessage = (Objects.equals(elytraReceivedMessage, new String("NONE")) ? null :
elytraLore = (Objects.equals(elytraLore, new String("NONE")) ? null : elytraLore ); elytraReceivedMessage);
elytraLore = (Objects.equals(elytraLore, new String("NONE")) ? null : elytraLore);
} }
public boolean playerHasCraftPerm(Player player, ArmorTier armorTier) public boolean playerHasCraftPerm(Player player, ArmorTier armorTier)
{ {
return getConfigLoader().bypassCraftPerm() || player.hasPermission("armoredelytra.craft." + ArmorTier.getName(armorTier)); return getConfigLoader().bypassCraftPerm() ||
player.hasPermission("armoredelytra.craft." + ArmorTier.getName(armorTier));
} }
public boolean playerHasWearPerm(Player player, ArmorTier armorTier) public boolean playerHasWearPerm(Player player, ArmorTier armorTier)
{ {
return getConfigLoader().bypassWearPerm() || player.hasPermission("armoredelytra.wear." + ArmorTier.getName(armorTier)); return getConfigLoader().bypassWearPerm() ||
player.hasPermission("armoredelytra.wear." + ArmorTier.getName(armorTier));
} }
// Returns true if this is the latest version of this plugin. // Returns true if this is the latest version of this plugin.
@ -244,7 +255,8 @@ public class ArmoredElytra extends JavaPlugin implements Listener
return string; return string;
} }
final ArmorTierName tierName = armorTierNames.get(armorTier); final ArmorTierName tierName = armorTierNames.get(armorTier);
return ARMOR_TIER_SHORT.matcher(ARMOR_TIER.matcher(string).replaceAll(ChatColor.stripColor(tierName.getLongName()))) return ARMOR_TIER_SHORT
.matcher(ARMOR_TIER.matcher(string).replaceAll(ChatColor.stripColor(tierName.getLongName())))
.replaceAll(ChatColor.stripColor(tierName.getShortName())); .replaceAll(ChatColor.stripColor(tierName.getShortName()));
} }
@ -271,8 +283,12 @@ public class ArmoredElytra extends JavaPlugin implements Listener
// Check + initialize for the correct version of Minecraft. // Check + initialize for the correct version of Minecraft.
public boolean compatibleMCVer() public boolean compatibleMCVer()
{ {
nbtEditor = new NBTEditor(this); return NBTEditor.success();
return nbtEditor.succes(); }
public static ArmoredElytra getInstance()
{
return instance;
} }
public String getElytraLore() public String getElytraLore()

View File

@ -1,7 +1,8 @@
package nl.pim16aap2.armoredElytra.handlers; package nl.pim16aap2.armoredElytra.handlers;
import java.util.logging.Level; import nl.pim16aap2.armoredElytra.ArmoredElytra;
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
@ -11,19 +12,15 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import nl.pim16aap2.armoredElytra.ArmoredElytra; import java.util.logging.Level;
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
public class CommandHandler implements CommandExecutor public class CommandHandler implements CommandExecutor
{ {
private final ArmoredElytra plugin; private final ArmoredElytra plugin;
private final NBTEditor nbtEditor;
public CommandHandler(ArmoredElytra plugin, NBTEditor nbtEditor) public CommandHandler(ArmoredElytra plugin)
{ {
this.plugin = plugin; this.plugin = plugin;
this.nbtEditor = nbtEditor;
} }
@Override @Override
@ -77,11 +74,13 @@ public class CommandHandler implements CommandExecutor
if (allowed) if (allowed)
{ {
plugin.elytraReceivedMessage(receiver, armorTier); plugin.elytraReceivedMessage(receiver, armorTier);
newElytra = nbtEditor.addArmorNBTTags(new ItemStack(Material.ELYTRA, 1), armorTier, plugin.getConfigLoader().unbreakable()); newElytra = NBTEditor.addArmorNBTTags(new ItemStack(Material.ELYTRA, 1), armorTier,
plugin.getConfigLoader().unbreakable());
plugin.giveArmoredElytraToPlayer(receiver, newElytra); plugin.giveArmoredElytraToPlayer(receiver, newElytra);
} }
else else
plugin.messagePlayer(player, plugin.fillInArmorTierInStringNoColor(plugin.getMyMessages().getString("MESSAGES.NoGivePermission"), armorTier)); plugin.messagePlayer(player, plugin.fillInArmorTierInStringNoColor(
plugin.getMyMessages().getString("MESSAGES.NoGivePermission"), armorTier));
return true; return true;
} }
} }
@ -96,7 +95,7 @@ public class CommandHandler implements CommandExecutor
if (args.length == 2) if (args.length == 2)
{ {
ItemStack newElytra = null; ItemStack newElytra = null;
String tier = args[1]; final String tier = args[1];
if (Bukkit.getPlayer(args[0]) != null) if (Bukkit.getPlayer(args[0]) != null)
{ {
player = Bukkit.getPlayer(args[0]); player = Bukkit.getPlayer(args[0]);
@ -106,9 +105,11 @@ public class CommandHandler implements CommandExecutor
return false; return false;
plugin.elytraReceivedMessage(player, armorTier); plugin.elytraReceivedMessage(player, armorTier);
newElytra = nbtEditor.addArmorNBTTags(new ItemStack(Material.ELYTRA, 1), armorTier, plugin.getConfigLoader().unbreakable()); newElytra = NBTEditor.addArmorNBTTags(new ItemStack(Material.ELYTRA, 1), armorTier,
plugin.getConfigLoader().unbreakable());
plugin.giveArmoredElytraToPlayer(player, newElytra); plugin.giveArmoredElytraToPlayer(player, newElytra);
plugin.myLogger(Level.INFO, ("Giving an armored elytra of the " + ArmorTier.getArmor(armorTier) + " armor tier to player " + player.getName())); plugin.myLogger(Level.INFO, ("Giving an armored elytra of the " + ArmorTier.getArmor(armorTier) +
" armor tier to player " + player.getName()));
return true; return true;
} }
plugin.myLogger(Level.INFO, ("Player " + args[1] + " not found!")); plugin.myLogger(Level.INFO, ("Player " + args[1] + " not found!"));

View File

@ -1,12 +1,16 @@
package nl.pim16aap2.armoredElytra.handlers; package nl.pim16aap2.armoredElytra.handlers;
import java.util.ArrayList; import com.codingforcookies.armorequip.ArmorEquipEvent;
import java.util.HashMap; import com.codingforcookies.armorequip.ArmorListener;
import java.util.Map; import com.codingforcookies.armorequip.ArmorType;
import java.util.Random; import com.codingforcookies.armorequip.DispenserArmorListener;
import java.util.function.Consumer; import nl.pim16aap2.armoredElytra.ArmoredElytra;
import java.util.logging.Level; import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
import nl.pim16aap2.armoredElytra.util.Action;
import nl.pim16aap2.armoredElytra.util.AllowedToWearEnum;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
import nl.pim16aap2.armoredElytra.util.Util;
import nl.pim16aap2.armoredElytra.util.XMaterial;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
@ -22,31 +26,23 @@ import org.bukkit.inventory.AnvilInventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta; import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import com.codingforcookies.armorequip.ArmorEquipEvent; import java.util.ArrayList;
import com.codingforcookies.armorequip.ArmorListener; import java.util.HashMap;
import com.codingforcookies.armorequip.ArmorType; import java.util.Map;
import com.codingforcookies.armorequip.DispenserArmorListener; import java.util.Random;
import java.util.function.Consumer;
import nl.pim16aap2.armoredElytra.ArmoredElytra; import java.util.logging.Level;
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
import nl.pim16aap2.armoredElytra.util.Action;
import nl.pim16aap2.armoredElytra.util.AllowedToWearEnum;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
import nl.pim16aap2.armoredElytra.util.Util;
import nl.pim16aap2.armoredElytra.util.XMaterial;
public class EventHandlers implements Listener public class EventHandlers implements Listener
{ {
private final NBTEditor nbtEditor;
private final ArmoredElytra plugin; private final ArmoredElytra plugin;
private final Consumer<AnvilInventory> cleanAnvilInventory; private final Consumer<AnvilInventory> cleanAnvilInventory;
private final Consumer<Player> moveChestplateToInventory; private final Consumer<Player> moveChestplateToInventory;
public EventHandlers(ArmoredElytra plugin, NBTEditor nbtEditor, boolean is1_9) public EventHandlers(ArmoredElytra plugin, boolean is1_9)
{ {
this.plugin = plugin; this.plugin = plugin;
this.nbtEditor = nbtEditor;
initializeArmorEquipEvent(); initializeArmorEquipEvent();
if (is1_9) if (is1_9)
{ {
@ -258,7 +254,7 @@ public class EventHandlers implements Listener
if (Util.isChestPlate(matTwo)) if (Util.isChestPlate(matTwo))
return Action.CREATE; return Action.CREATE;
ArmorTier tier = nbtEditor.getArmorTier(itemOne); ArmorTier tier = NBTEditor.getArmorTier(itemOne);
if (tier != ArmorTier.NONE) if (tier != ArmorTier.NONE)
{ {
@ -272,7 +268,7 @@ public class EventHandlers implements Listener
// If the armored elytra is to be combined with another armored elytra of the // If the armored elytra is to be combined with another armored elytra of the
// same tier... // same tier...
if (nbtEditor.getArmorTier(itemTwo) == tier) if (NBTEditor.getArmorTier(itemTwo) == tier)
return Action.COMBINE; return Action.COMBINE;
// If the armored elytra is not of the leather tier, but itemTwo is leather, // If the armored elytra is not of the leather tier, but itemTwo is leather,
@ -309,7 +305,7 @@ public class EventHandlers implements Listener
{ {
Action action = isValidInput(itemA, itemB); Action action = isValidInput(itemA, itemB);
ArmorTier newTier = ArmorTier.NONE; ArmorTier newTier = ArmorTier.NONE;
ArmorTier curTier = nbtEditor.getArmorTier(itemA); ArmorTier curTier = NBTEditor.getArmorTier(itemA);
short durability = 0; short durability = 0;
Map<Enchantment, Integer> enchantments = itemA.getEnchantments(); Map<Enchantment, Integer> enchantments = itemA.getEnchantments();
enchantments = fixEnchantments(enchantments); enchantments = fixEnchantments(enchantments);
@ -359,14 +355,14 @@ public class EventHandlers implements Listener
result.addUnsafeEnchantments(enchantments); result.addUnsafeEnchantments(enchantments);
result.setDurability(durability); result.setDurability(durability);
result = nbtEditor.addArmorNBTTags(result, newTier, plugin.getConfigLoader().unbreakable()); result = NBTEditor.addArmorNBTTags(result, newTier, plugin.getConfigLoader().unbreakable());
event.setResult(result); event.setResult(result);
} }
} }
// Check if either itemA or itemB is unoccupied. // Check if either itemA or itemB is unoccupied.
if ((itemA == null || itemB == null) && if ((itemA == null || itemB == null) &&
nbtEditor.getArmorTier(event.getInventory().getItem(2)) != ArmorTier.NONE) NBTEditor.getArmorTier(event.getInventory().getItem(2)) != ArmorTier.NONE)
// If Item2 is occupied despite itemA or itemB not being occupied. (only for // If Item2 is occupied despite itemA or itemB not being occupied. (only for
// armored elytra)/ // armored elytra)/
event.setResult(null); event.setResult(null);
@ -386,7 +382,6 @@ public class EventHandlers implements Listener
return; return;
AnvilInventory anvilInventory; AnvilInventory anvilInventory;
// Try to cast inventory being used in the event to an anvil inventory. // Try to cast inventory being used in the event to an anvil inventory.
// This will throw a ClassCastException when a CraftInventoryCustom is used. // This will throw a ClassCastException when a CraftInventoryCustom is used.
try try
@ -399,6 +394,7 @@ public class EventHandlers implements Listener
// custom inventories as they are usually used for GUI's). // custom inventories as they are usually used for GUI's).
plugin.debugMsg(Level.WARNING, "Could not cast inventory to anvilInventory for player " + player.getName() 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; return;
} }
@ -407,7 +403,8 @@ public class EventHandlers implements Listener
if (slot == 2 && anvilInventory.getItem(0) != null && anvilInventory.getItem(1) != null && if (slot == 2 && anvilInventory.getItem(0) != null && anvilInventory.getItem(1) != null &&
anvilInventory.getItem(2) != null) anvilInventory.getItem(2) != null)
{ {
ArmorTier armortier = nbtEditor.getArmorTier(anvilInventory.getItem(2)); ArmorTier armortier = NBTEditor.getArmorTier(anvilInventory.getItem(2));
// If there's an armored elytra in the final slot... // If there's an armored elytra in the final slot...
if (armortier != ArmorTier.NONE && plugin.playerHasCraftPerm(player, armortier)) if (armortier != ArmorTier.NONE && plugin.playerHasCraftPerm(player, armortier))
{ {
@ -415,8 +412,9 @@ public class EventHandlers implements Listener
// result. // result.
// This is done because after putting item0 in AFTER item1, the first letter of // This is done because after putting item0 in AFTER item1, the first letter of
// the color code shows up, this gets rid of that problem. // the color code shows up, this gets rid of that problem.
ItemStack result = nbtEditor.addArmorNBTTags(anvilInventory.getItem(2), armortier, ItemStack result = NBTEditor.addArmorNBTTags(anvilInventory.getItem(2), armortier,
plugin.getConfigLoader().unbreakable()); plugin.getConfigLoader().unbreakable());
// Give the result to the player and clear the anvil's inventory. // Give the result to the player and clear the anvil's inventory.
if (e.isShiftClick()) if (e.isShiftClick())
{ {
@ -427,6 +425,7 @@ public class EventHandlers implements Listener
} }
else else
player.setItemOnCursor(result); player.setItemOnCursor(result);
// Clean the anvil's inventory after transferring the items. // Clean the anvil's inventory after transferring the items.
cleanAnvilInventory.accept(anvilInventory); cleanAnvilInventory.accept(anvilInventory);
player.updateInventory(); player.updateInventory();
@ -465,7 +464,7 @@ public class EventHandlers implements Listener
if (p.getInventory().getChestplate() == null) if (p.getInventory().getChestplate() == null)
return; return;
if (nbtEditor.getArmorTier(p.getInventory().getChestplate()) == ArmorTier.NONE) if (NBTEditor.getArmorTier(p.getInventory().getChestplate()) == ArmorTier.NONE)
return; return;
ItemStack elytra = p.getInventory().getChestplate(); ItemStack elytra = p.getInventory().getChestplate();
@ -510,14 +509,18 @@ public class EventHandlers implements Listener
@EventHandler @EventHandler
public void onEquip(ArmorEquipEvent e) public void onEquip(ArmorEquipEvent e)
{ {
if (!e.getType().equals(ArmorType.CHESTPLATE) || if (e.getMethod().equals(ArmorEquipEvent.EquipMethod.DEATH) ||
e.getNewArmorPiece() == null || e.getMethod().equals(ArmorEquipEvent.EquipMethod.BROKE))
!e.getNewArmorPiece().getType().equals(Material.ELYTRA) )
return; return;
ArmorTier armorTier = nbtEditor.getArmorTier(e.getNewArmorPiece()); if (!e.getType().equals(ArmorType.CHESTPLATE) ||
e.getNewArmorPiece() == null ||
!e.getNewArmorPiece().getType().equals(Material.ELYTRA))
return;
ArmorTier armorTier = NBTEditor.getArmorTier(e.getNewArmorPiece());
AllowedToWearEnum allowed = isAllowedToWear(e.getNewArmorPiece(), e.getPlayer(), armorTier); AllowedToWearEnum allowed = isAllowedToWear(e.getNewArmorPiece(), e.getPlayer(), armorTier);
switch(allowed) switch (allowed)
{ {
case ALLOWED: case ALLOWED:
break; break;

View File

@ -1,20 +1,16 @@
package nl.pim16aap2.armoredElytra.handlers; package nl.pim16aap2.armoredElytra.handlers;
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerItemDamageEvent; import org.bukkit.event.player.PlayerItemDamageEvent;
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
public class FlyDurabilityHandler implements Listener public class FlyDurabilityHandler implements Listener
{ {
private final NBTEditor nbtEditor; public FlyDurabilityHandler()
public FlyDurabilityHandler(NBTEditor nbtEditor)
{ {
this.nbtEditor = nbtEditor;
} }
// Do not decrease elytra durability while flying. This also cancels durability decrease when // Do not decrease elytra durability while flying. This also cancels durability decrease when
@ -24,10 +20,11 @@ public class FlyDurabilityHandler implements Listener
{ {
if (e.getItem().getType() != Material.ELYTRA) if (e.getItem().getType() != Material.ELYTRA)
return; return;
if (!e.getPlayer().isFlying())
if (!e.getPlayer().isGliding())
return; return;
if (nbtEditor.getArmorTier(e.getItem()) != ArmorTier.NONE) if (NBTEditor.getArmorTier(e.getItem()) != ArmorTier.NONE)
e.setCancelled(true); e.setCancelled(true);
} }
} }

View File

@ -1,5 +1,8 @@
package nl.pim16aap2.armoredElytra.handlers; package nl.pim16aap2.armoredElytra.handlers;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -12,19 +15,13 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
public class Uninstaller implements Listener public class Uninstaller implements Listener
{ {
private final ArmoredElytra plugin; private final ArmoredElytra plugin;
private final NBTEditor nbtEditor;
public Uninstaller(ArmoredElytra plugin, NBTEditor nbtEditor) public Uninstaller(ArmoredElytra plugin)
{ {
this.plugin = plugin; this.plugin = plugin;
this.nbtEditor = nbtEditor;
} }
public int removeArmoredElytras(Inventory inv) public int removeArmoredElytras(Inventory inv)
@ -33,7 +30,7 @@ public class Uninstaller implements Listener
for (ItemStack is : inv) for (ItemStack is : inv)
if (is != null) if (is != null)
if (is.getType() == Material.ELYTRA) if (is.getType() == Material.ELYTRA)
if (nbtEditor.getArmorTier(is) != ArmorTier.NONE) if (NBTEditor.getArmorTier(is) != ArmorTier.NONE)
{ {
inv.remove(is); inv.remove(is);
++count; ++count;
@ -54,7 +51,8 @@ public class Uninstaller implements Listener
Inventory inv = event.getInventory(); Inventory inv = event.getInventory();
int removed = removeArmoredElytras(inv); int removed = removeArmoredElytras(inv);
if (removed != 0) if (removed != 0)
plugin.messagePlayer((Player) (event.getPlayer()), ChatColor.RED, "Removed " + removed + " armored elytras from your chest!"); plugin.messagePlayer((Player) (event.getPlayer()), ChatColor.RED,
"Removed " + removed + " armored elytras from your chest!");
} }
}.runTaskLater(plugin, 20); }.runTaskLater(plugin, 20);
} }
@ -71,7 +69,8 @@ public class Uninstaller implements Listener
Inventory inv = event.getPlayer().getInventory(); Inventory inv = event.getPlayer().getInventory();
int removed = removeArmoredElytras(inv); int removed = removeArmoredElytras(inv);
if (removed != 0) if (removed != 0)
plugin.messagePlayer(event.getPlayer(), ChatColor.RED, "Removed " + removed + " armored elytras from your inventory!"); plugin.messagePlayer(event.getPlayer(), ChatColor.RED,
"Removed " + removed + " armored elytras from your inventory!");
} }
}.runTaskLater(plugin, 20); }.runTaskLater(plugin, 20);
} }

View File

@ -1,6 +0,0 @@
package nl.pim16aap2.armoredElytra.nbtEditor;
public interface GetArmorValue
{
public int armorValueFromNBTString(String nbtString);
}

View File

@ -1,33 +0,0 @@
package nl.pim16aap2.armoredElytra.nbtEditor;
import java.util.logging.Level;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
public class GetArmorValueNew implements GetArmorValue
{
private final ArmoredElytra plugin;
public GetArmorValueNew(ArmoredElytra plugin)
{
this.plugin = plugin;
}
@Override
public int armorValueFromNBTString(String nbtString)
{
int pos = nbtString.indexOf(",Slot:\"chest\",AttributeName:\"generic.armor\"");
if (pos > 0)
try
{
String stringAtPos = nbtString.substring(pos - 4, pos - 1);
return (int) Double.parseDouble(stringAtPos);
}
catch (Exception e)
{
plugin.myLogger(Level.INFO, "Failed to obtain armor value from NBT!");
return 0;
}
return 0;
}
}

View File

@ -1,26 +0,0 @@
package nl.pim16aap2.armoredElytra.nbtEditor;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
public class GetArmorValueOld implements GetArmorValue
{
private final ArmoredElytra plugin;
public GetArmorValueOld(ArmoredElytra plugin)
{
this.plugin = plugin;
}
@Override
public int armorValueFromNBTString(String nbtString)
{
int pos = nbtString.indexOf(",Slot:\"chest\",AttributeName:\"generic.armor\"");
if (pos > 0)
{
pos--;
String stringAtPos = nbtString.substring(pos, pos + 1);
return Integer.parseInt(stringAtPos);
}
return 0;
}
}

View File

@ -1,100 +1,80 @@
package nl.pim16aap2.armoredElytra.nbtEditor; package nl.pim16aap2.armoredElytra.nbtEditor;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
import java.util.function.Function;
import org.bukkit.Bukkit; import java.util.logging.Level;
import org.bukkit.Material; import java.util.regex.Matcher;
import org.bukkit.inventory.ItemStack; import java.util.regex.Pattern;
import org.bukkit.inventory.meta.ItemMeta;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
public class NBTEditor public class NBTEditor
{ {
private final ArmoredElytra plugin; private static final String versionString = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
private final String NMSbase; private static final MinecraftVersion minecraftVersion = MinecraftVersion.get(versionString);
private final String CraftBase; private static final String NMSbase = "net.minecraft.server." + versionString + ".";
private Method asNMSCopy; private static final String CraftBase = "org.bukkit.craftbukkit." + versionString + ".";
private Method asBukkitCopy;
private Class<?> NMSItemStack;
private Class<?> CraftItemStack;
private Class<?> NBTTagCompound; private static Method asNMSCopy;
private Class<?> NBTTagList; private static Method asBukkitCopy;
private Class<?> NBTBase; private static Class<?> NMSItemStack;
private Class<?> NBTTagString; private static Class<?> CraftItemStack;
private Class<?> NBTTagByte;
private Class<?> NBTTagInt;
private Method hasTag; private static Class<?> NBTTagCompound;
private Method getTag; private static Class<?> NBTTagList;
private static Class<?> NBTBase;
private static Class<?> NBTTagString;
private static Class<?> NBTTagByte;
private static Class<?> NBTTagInt;
private Method addCompound; private static Method hasTag;
private static Method getTag;
private Method setTag; private static Method addCompound;
private Method setCompoundByte; private static Method setTag;
private Method setCompoundTagList;
private Constructor<?> NBTTagStringCtor; private static Method setCompoundByte;
private Constructor<?> NBTTagByteCtor; private static Method setCompoundTagList;
private Constructor<?> NBTTagIntCtor;
private boolean success = false; private static Method getCompoundTagList;
private GetArmorValue getArmorValue; private static Method getTagListSize;
private static Method getTagListAtIndex;
public NBTEditor(ArmoredElytra plugin) private static Constructor<?> NBTTagStringCtor;
{ private static Constructor<?> NBTTagByteCtor;
this.plugin = plugin; private static Constructor<?> NBTTagIntCtor;
final String versionString = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
NMSbase = "net.minecraft.server." + versionString + "."; private static boolean success;
CraftBase = "org.bukkit.craftbukkit." + versionString + ".";
private static Function<String, Integer> getArmorValue;
constructNMSClasses();
getTagReadingMethod();
} private static final Pattern pattern_findAmount_double = Pattern.compile("Amount:[0-9]+.[0-9]+d[,}]*");
private static final Pattern pattern_findAmount_int = Pattern.compile("Amount:[0-9]+[,}]*");
private void getTagReadingMethod() private static final Pattern pattern_getDouble = Pattern.compile("[0-9]+.[0-9]+");
{ private static final Pattern pattern_getInt = Pattern.compile("[0-9]+");
if (!success) private static final Pattern pattern_isArmor = Pattern.compile("\"generic.armor\"");
return;
String version; static
try
{
version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
}
catch (final ArrayIndexOutOfBoundsException useAVersionMentionedInTheDescriptionPleaseException)
{ {
if (minecraftVersion == null)
success = false; success = false;
return;
}
// Old versions use the old format. It is assumed here that all versions from
// 1.13.2 on will use the new format.
// Spigot's 1.13.1 uses the old format, but 1.13.2 uses the new format. They
// share the same version number though.
if (version.equals("v1_9_R1") || version.equals("v1_9_R2") || version.equals("v1_10_R1") ||
version.equals("v1_11_R1") || version.equals("v1_12_R1") || version.equals("v1_13_R1") ||
version.equals("v1_13_R2") && Bukkit.getVersion().split(" ")[2].equals("1.13.1)"))
getArmorValue = new GetArmorValueOld(plugin);
else else
getArmorValue = new GetArmorValueNew(plugin);
}
public boolean succes()
{
return success;
}
private void constructNMSClasses()
{
try try
{ {
// 1.13 and lower use integer armor values while 1.14 and newer use double armor values.
getArmorValue = minecraftVersion.isNewerThan(MinecraftVersion.v1_13) ?
NBTEditor::getArmorValueDouble : NBTEditor::getArmorValueInt;
NMSItemStack = getNMSClass("ItemStack"); NMSItemStack = getNMSClass("ItemStack");
hasTag = NMSItemStack.getMethod("hasTag"); hasTag = NMSItemStack.getMethod("hasTag");
getTag = NMSItemStack.getMethod("getTag"); getTag = NMSItemStack.getMethod("getTag");
@ -121,6 +101,8 @@ public class NBTEditor
setTag = NBTTagCompound.getMethod("set", String.class, NBTBase); setTag = NBTTagCompound.getMethod("set", String.class, NBTBase);
NBTTagList = getNMSClass("NBTTagList"); NBTTagList = getNMSClass("NBTTagList");
getTagListSize = NBTTagList.getMethod("size");
getTagListAtIndex = NBTTagList.getMethod("get", int.class);
// Starting in 1.14, you also need to provide an int value when adding nbt tags. // Starting in 1.14, you also need to provide an int value when adding nbt tags.
try try
{ {
@ -133,6 +115,7 @@ public class NBTEditor
setCompoundTagList = NBTTagCompound.getMethod("set", String.class, NBTBase); setCompoundTagList = NBTTagCompound.getMethod("set", String.class, NBTBase);
setCompoundByte = NBTTagCompound.getMethod("set", String.class, NBTBase); setCompoundByte = NBTTagCompound.getMethod("set", String.class, NBTBase);
getCompoundTagList = NBTTagCompound.getMethod("getList", String.class, int.class);
success = true; success = true;
} }
@ -143,7 +126,7 @@ public class NBTEditor
} }
} }
private void addCompound(Object instance, Object nbtbase) private static void addCompound(Object instance, Object nbtbase)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
{ {
if (addCompound.getParameterCount() == 2) if (addCompound.getParameterCount() == 2)
@ -153,7 +136,7 @@ public class NBTEditor
} }
// Add armor to the supplied item, based on the armorTier. // Add armor to the supplied item, based on the armorTier.
public ItemStack addArmorNBTTags(ItemStack item, ArmorTier armorTier, boolean unbreakable) public static ItemStack addArmorNBTTags(ItemStack item, ArmorTier armorTier, boolean unbreakable)
{ {
try try
{ {
@ -161,10 +144,12 @@ public class NBTEditor
int armorProtection = ArmorTier.getArmor(armorTier); int armorProtection = ArmorTier.getArmor(armorTier);
int armorToughness = ArmorTier.getToughness(armorTier); int armorToughness = ArmorTier.getToughness(armorTier);
itemmeta.setDisplayName(plugin.getArmoredElytraName(armorTier)); itemmeta.setDisplayName(ArmoredElytra.getInstance().getArmoredElytraName(armorTier));
if (plugin.getElytraLore() != null) if (ArmoredElytra.getInstance().getElytraLore() != null)
itemmeta itemmeta
.setLore(Arrays.asList(plugin.fillInArmorTierInStringNoColor(plugin.getElytraLore(), armorTier))); .setLore(Arrays.asList(ArmoredElytra.getInstance().fillInArmorTierInStringNoColor(
ArmoredElytra.getInstance().getElytraLore(), armorTier)));
item.setItemMeta(itemmeta); item.setItemMeta(itemmeta);
Object nmsStack = asNMSCopy.invoke(null, item); Object nmsStack = asNMSCopy.invoke(null, item);
@ -196,33 +181,118 @@ public class NBTEditor
setCompoundTagList.invoke(compound, "AttributeModifiers", modifiers); setCompoundTagList.invoke(compound, "AttributeModifiers", modifiers);
item = (ItemStack) asBukkitCopy.invoke(null, nmsStack); item = (ItemStack) asBukkitCopy.invoke(null, nmsStack);
} }
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e)
{ {
// TODO: Log this or something. Pretty serious issue for a plugin based entirely
// on this code.
e.printStackTrace(); e.printStackTrace();
} }
return item; return item;
} }
// Get the armor tier of the supplied item. /**
public ArmorTier getArmorTier(ItemStack item) * Gets the armor amount from an NBT attribute.
*
* @param string The NBT attribute as a String.
* @param findAmount The {@link Pattern} that finds the amount in a String.
* @param parseAmount The {@link Pattern} that extracts the amount from the String found by "findAmount".
* @return The String containing the armor value. This can either be an integer or a double value.
*/
private static String getArmorAmount(final String string, final Pattern findAmount, final Pattern parseAmount)
{
final Matcher amountMatcher = findAmount.matcher(string);
if (!amountMatcher.find())
{
ArmoredElytra.getInstance()
.myLogger(Level.SEVERE,
"Failed to obtain armor value from NBT! No armor amount found: " + string);
return "0";
}
final String amountName = amountMatcher.group();
final Matcher amountString = parseAmount.matcher(amountName);
if (!amountString.find())
{
ArmoredElytra.getInstance()
.myLogger(Level.SEVERE,
"Failed to obtain armor value from NBT! Could not parse value: " + amountName);
return "0";
}
return amountString.group();
}
/**
* Gets the amount of an attribute in the format of: "something something, amount:2.0d,". The amount is cast to and
* returned as an integer value.
*
* @param string The nbt attribute as String.
* @return The integer value of the amount.
*/
private static int getArmorValueDouble(final String string)
{ {
try try
{ {
if (item == null) return (int) Double.parseDouble(getArmorAmount(string, pattern_findAmount_double, pattern_getDouble));
return ArmorTier.NONE; }
if (item.getType() != Material.ELYTRA) catch (NumberFormatException e)
return ArmorTier.NONE; {
e.printStackTrace();
}
return 0;
}
// Get the NBT tags from the item. /**
* Gets the amount of an attribute in the format of: "something something, amount:2.0d,". The amount is cast to and
* returned as an integer value.
*
* @param string The nbt attribute as String.
* @return The integer value of the amount.
*/
private static int getArmorValueInt(final String string)
{
try
{
return Integer.parseInt(getArmorAmount(string, pattern_findAmount_int, pattern_getInt));
}
catch (NumberFormatException e)
{
e.printStackTrace();
}
return 0;
}
public static ArmorTier getArmorTier(ItemStack item)
{
// {
// double armorValue_2 = 0;
// net.minecraft.server.v1_15_R1.ItemStack nmsStack_2 = org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack
// .asNMSCopy(item);
//
// net.minecraft.server.v1_15_R1.NBTTagCompound compound_2 =
// nmsStack_2.hasTag() ? nmsStack_2.getTag() : new net.minecraft.server.v1_15_R1.NBTTagCompound();
//
// net.minecraft.server.v1_15_R1.NBTTagList modifiers_2 = compound_2.getList("AttributeModifiers", 10);
// }
try
{
Object compound = getTag.invoke(asNMSCopy.invoke(null, item)); Object compound = getTag.invoke(asNMSCopy.invoke(null, item));
if (compound == null) if (compound == null)
return ArmorTier.NONE; return ArmorTier.NONE;
switch (getArmorValue.armorValueFromNBTString(compound.toString())) Object modifiers = getCompoundTagList.invoke(compound, "AttributeModifiers", 10); // Number 10 = Compound.
int size = (int) getTagListSize.invoke(modifiers);
for (int idx = 0; idx < size; ++idx)
{
// final String result = modifiers.get(idx).asString();
final String result = getTagListAtIndex.invoke(modifiers, idx).toString();
if (!pattern_isArmor.matcher(result).find())
continue;
int armorValue = getArmorValue.apply(result);
switch (armorValue)
{ {
case 3: case 3:
return ArmorTier.LEATHER; return ArmorTier.LEATHER;
@ -236,20 +306,70 @@ public class NBTEditor
return ArmorTier.NONE; return ArmorTier.NONE;
} }
} }
return ArmorTier.NONE;
}
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
{ {
e.printStackTrace(); e.printStackTrace();
return null; return ArmorTier.NONE;
} }
} }
private Class<?> getNMSClass(String name) throws ClassNotFoundException private static Class<?> getNMSClass(String name)
throws ClassNotFoundException
{ {
return Class.forName(NMSbase + name); return Class.forName(NMSbase + name);
} }
private Class<?> getCraftClass(String name) throws ClassNotFoundException private static Class<?> getCraftClass(String name)
throws ClassNotFoundException
{ {
return Class.forName(CraftBase + name); return Class.forName(CraftBase + name);
} }
public static boolean success()
{
return success;
}
private enum MinecraftVersion
{
v1_9("1_9", 0),
v1_10("1_10", 1),
v1_11("1_11", 2),
v1_12("1_12", 3),
v1_13("1_13", 4),
v1_14("1_14", 5),
v1_15("1_15", 6);
private int index;
private String name;
MinecraftVersion(String name, int index)
{
this.name = name;
this.index = index;
}
/**
* Checks if this version is newer than the other version.
*
* @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)
{
return this.index > other.index;
}
public static MinecraftVersion get(final String versionName)
{
if (versionName == null)
return null;
for (final MinecraftVersion mcVersion : MinecraftVersion.values())
if (versionName.contains(mcVersion.name))
return mcVersion;
return null;
}
}
} }