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:
parent
19ab2cdab1
commit
51854fa150
30
pom.xml
30
pom.xml
@ -1,6 +1,6 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>nl.pim16aap2</groupId>
|
||||
<artifactId>ArmoredElytra</artifactId>
|
||||
@ -11,10 +11,14 @@
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
|
||||
<!-- bStats -->
|
||||
<repository>
|
||||
<id>CodeMC</id>
|
||||
<url>https://repo.codemc.org/repository/maven-public</url>
|
||||
<url>https://repo.codemc.org/repository/maven-public/</url>
|
||||
</repository>
|
||||
|
||||
<!-- Item-NBT-API-->
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
@ -22,17 +26,19 @@
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spigot API (docs) -->
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.14.2-R0.1-SNAPSHOT</version>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.15.1-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Spigot API + (Craft)Bukkit API + NMS -->
|
||||
<dependency>
|
||||
<groupId>com.github.tr7zw</groupId>
|
||||
<artifactId>Item-NBT-API</artifactId>
|
||||
<version>master-SNAPSHOT</version>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.15.1-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@ -43,7 +49,7 @@
|
||||
<version>1.5</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>com.github.Arnuh</groupId>
|
||||
@ -86,10 +92,6 @@
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>nl.pim16aap2.armoredElytra</shadedPattern>
|
||||
</relocation>
|
||||
<!--<relocation>
|
||||
<pattern>com.codingforcookies</pattern>
|
||||
<shadedPattern>nl.pim16aap2.armoredElytra</shadedPattern>
|
||||
</relocation>-->
|
||||
</relocations>
|
||||
</configuration>
|
||||
<executions>
|
||||
@ -124,7 +126,7 @@
|
||||
<configuration>
|
||||
<target>
|
||||
<ant antfile="${basedir}/mover.xml">
|
||||
<target name="copyAll" />
|
||||
<target name="copyAll"/>
|
||||
</ant>
|
||||
</target>
|
||||
</configuration>
|
||||
|
@ -1,19 +1,5 @@
|
||||
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.EventHandlers;
|
||||
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.Messages;
|
||||
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: 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
|
||||
{
|
||||
private NBTEditor nbtEditor;
|
||||
private static ArmoredElytra instance;
|
||||
private Messages messages;
|
||||
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 String elytraReceivedMessage;
|
||||
private String usageDeniedMessage;
|
||||
@ -48,6 +47,7 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
@Override
|
||||
public void onEnable()
|
||||
{
|
||||
instance = this;
|
||||
config = new ConfigLoader(this);
|
||||
messages = new Messages(this);
|
||||
readMessages();
|
||||
@ -56,60 +56,68 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
if (config.checkForUpdates())
|
||||
{
|
||||
// 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 ArmoredElytra plugin = getPlugin();
|
||||
final Update update = new Update(278437, plugin);
|
||||
final String latestVersion = update.getLatestVersion();
|
||||
|
||||
if (latestVersion == null)
|
||||
plugin.myLogger(Level.WARNING, "Encountered problem contacting update servers! Please check manually! The error above does not affect the plugin!");
|
||||
else
|
||||
final Thread thread = new Thread(
|
||||
() ->
|
||||
{
|
||||
final String thisVersion = plugin.getDescription().getVersion();
|
||||
// Check if this is the latest version or not.
|
||||
final int updateStatus = update.versionCompare(latestVersion, thisVersion);
|
||||
final ArmoredElytra plugin = getPlugin();
|
||||
final Update update = new Update(278437, plugin);
|
||||
final String latestVersion = update.getLatestVersion();
|
||||
|
||||
if (updateStatus > 0)
|
||||
{
|
||||
// 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);
|
||||
plugin.myLogger(Level.INFO, "Plugin out of date! You are using version " + thisVersion + " but the latest version is version " + latestVersion + "!");
|
||||
plugin.setUpToDate(false);
|
||||
}
|
||||
if (latestVersion == null)
|
||||
plugin.myLogger(Level.WARNING,
|
||||
"Encountered problem contacting update servers! Please check manually! The error above does not affect the plugin!");
|
||||
else
|
||||
{
|
||||
plugin.setUpToDate(true);
|
||||
plugin.myLogger(Level.INFO, "You seem to be using the latest version of this plugin!");
|
||||
final String thisVersion = plugin.getDescription().getVersion();
|
||||
// Check if this is the latest version or not.
|
||||
final int updateStatus = update.versionCompare(latestVersion, thisVersion);
|
||||
|
||||
if (updateStatus > 0)
|
||||
{
|
||||
// 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);
|
||||
plugin.myLogger(Level.INFO, "Plugin out of date! You are using version " + thisVersion +
|
||||
" but the latest version is version " + latestVersion + "!");
|
||||
plugin.setUpToDate(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
plugin.setUpToDate(true);
|
||||
plugin.myLogger(Level.INFO, "You seem to be using the latest version of this plugin!");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
thread.start();
|
||||
}
|
||||
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())
|
||||
{
|
||||
myLogger(Level.INFO, "Enabling stats! Thanks, it really helps!");
|
||||
@SuppressWarnings("unused")
|
||||
final
|
||||
Metrics metrics = new Metrics(this);
|
||||
@SuppressWarnings("unused") final Metrics metrics = new Metrics(this);
|
||||
}
|
||||
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!");
|
||||
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.
|
||||
if (compatibleMCVer())
|
||||
{
|
||||
Bukkit.getPluginManager().registerEvents(new EventHandlers(this, nbtEditor, is1_9), this);
|
||||
getCommand("ArmoredElytra").setExecutor(new CommandHandler(this, nbtEditor));
|
||||
Bukkit.getPluginManager().registerEvents(new EventHandlers(this, is1_9), this);
|
||||
getCommand("ArmoredElytra").setExecutor(new CommandHandler(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
Bukkit.getPluginManager().registerEvents(new LoginHandler(this, "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!");
|
||||
Bukkit.getPluginManager().registerEvents(new LoginHandler(this,
|
||||
"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;
|
||||
}
|
||||
|
||||
@ -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.
|
||||
if (config.noFlightDurability())
|
||||
{
|
||||
Bukkit.getPluginManager().registerEvents(new FlyDurabilityHandler(nbtEditor), this);
|
||||
myLogger(Level.INFO, "Durability penalty for flying enabled!");
|
||||
Bukkit.getPluginManager().registerEvents(new FlyDurabilityHandler(), this);
|
||||
myLogger(Level.INFO, "Durability penalty for flying disabled!");
|
||||
}
|
||||
else
|
||||
myLogger(Level.INFO, "Durability penalty for flying disabled!");
|
||||
myLogger(Level.INFO, "Durability penalty for flying enabled!");
|
||||
|
||||
// Log all allowed enchantments.
|
||||
myLogger(Level.INFO, ("Allowed enchantments:"));
|
||||
@ -133,7 +141,7 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
else
|
||||
{
|
||||
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")));
|
||||
|
||||
// Change the string to null if it says "NONE".
|
||||
usageDeniedMessage = (Objects.equals(usageDeniedMessage, new String("NONE")) ? null : usageDeniedMessage );
|
||||
elytraReceivedMessage = (Objects.equals(elytraReceivedMessage, new String("NONE")) ? null : elytraReceivedMessage);
|
||||
elytraLore = (Objects.equals(elytraLore, new String("NONE")) ? null : elytraLore );
|
||||
usageDeniedMessage = (Objects.equals(usageDeniedMessage, new String("NONE")) ? null : usageDeniedMessage);
|
||||
elytraReceivedMessage = (Objects.equals(elytraReceivedMessage, new String("NONE")) ? null :
|
||||
elytraReceivedMessage);
|
||||
elytraLore = (Objects.equals(elytraLore, new String("NONE")) ? null : elytraLore);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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.
|
||||
@ -244,7 +255,8 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
return string;
|
||||
}
|
||||
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()));
|
||||
}
|
||||
|
||||
@ -271,8 +283,12 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
// Check + initialize for the correct version of Minecraft.
|
||||
public boolean compatibleMCVer()
|
||||
{
|
||||
nbtEditor = new NBTEditor(this);
|
||||
return nbtEditor.succes();
|
||||
return NBTEditor.success();
|
||||
}
|
||||
|
||||
public static ArmoredElytra getInstance()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
public String getElytraLore()
|
||||
@ -294,4 +310,4 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
{
|
||||
this.upToDate = upToDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
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.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
@ -11,19 +12,15 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class CommandHandler implements CommandExecutor
|
||||
{
|
||||
private final ArmoredElytra plugin;
|
||||
private final NBTEditor nbtEditor;
|
||||
|
||||
public CommandHandler(ArmoredElytra plugin, NBTEditor nbtEditor)
|
||||
public CommandHandler(ArmoredElytra plugin)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.nbtEditor = nbtEditor;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -52,7 +49,7 @@ public class CommandHandler implements CommandExecutor
|
||||
if (args.length == 1)
|
||||
{
|
||||
receiver = player;
|
||||
tier = args[0];
|
||||
tier = args[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -77,11 +74,13 @@ public class CommandHandler implements CommandExecutor
|
||||
if (allowed)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -96,7 +95,7 @@ public class CommandHandler implements CommandExecutor
|
||||
if (args.length == 2)
|
||||
{
|
||||
ItemStack newElytra = null;
|
||||
String tier = args[1];
|
||||
final String tier = args[1];
|
||||
if (Bukkit.getPlayer(args[0]) != null)
|
||||
{
|
||||
player = Bukkit.getPlayer(args[0]);
|
||||
@ -106,9 +105,11 @@ public class CommandHandler implements CommandExecutor
|
||||
return false;
|
||||
|
||||
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.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;
|
||||
}
|
||||
plugin.myLogger(Level.INFO, ("Player " + args[1] + " not found!"));
|
||||
|
@ -1,12 +1,16 @@
|
||||
package nl.pim16aap2.armoredElytra.handlers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.codingforcookies.armorequip.ArmorEquipEvent;
|
||||
import com.codingforcookies.armorequip.ArmorListener;
|
||||
import com.codingforcookies.armorequip.ArmorType;
|
||||
import com.codingforcookies.armorequip.DispenserArmorListener;
|
||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||
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.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
@ -22,31 +26,23 @@ import org.bukkit.inventory.AnvilInventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||
|
||||
import com.codingforcookies.armorequip.ArmorEquipEvent;
|
||||
import com.codingforcookies.armorequip.ArmorListener;
|
||||
import com.codingforcookies.armorequip.ArmorType;
|
||||
import com.codingforcookies.armorequip.DispenserArmorListener;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||
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 java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class EventHandlers implements Listener
|
||||
{
|
||||
private final NBTEditor nbtEditor;
|
||||
private final ArmoredElytra plugin;
|
||||
|
||||
private final Consumer<AnvilInventory> cleanAnvilInventory;
|
||||
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.nbtEditor = nbtEditor;
|
||||
initializeArmorEquipEvent();
|
||||
if (is1_9)
|
||||
{
|
||||
@ -164,21 +160,21 @@ public class EventHandlers implements Listener
|
||||
if (protVal0 != 0 && protVal1 != 0 && protVal0 != protVal1)
|
||||
switch (protVal0)
|
||||
{
|
||||
case 1:
|
||||
combined.remove(Enchantment.PROTECTION_ENVIRONMENTAL);
|
||||
break;
|
||||
case 2:
|
||||
combined.remove(Enchantment.PROTECTION_EXPLOSIONS);
|
||||
break;
|
||||
case 4:
|
||||
combined.remove(Enchantment.PROTECTION_FALL);
|
||||
break;
|
||||
case 8:
|
||||
combined.remove(Enchantment.PROTECTION_FIRE);
|
||||
break;
|
||||
case 16:
|
||||
combined.remove(Enchantment.PROTECTION_PROJECTILE);
|
||||
break;
|
||||
case 1:
|
||||
combined.remove(Enchantment.PROTECTION_ENVIRONMENTAL);
|
||||
break;
|
||||
case 2:
|
||||
combined.remove(Enchantment.PROTECTION_EXPLOSIONS);
|
||||
break;
|
||||
case 4:
|
||||
combined.remove(Enchantment.PROTECTION_FALL);
|
||||
break;
|
||||
case 8:
|
||||
combined.remove(Enchantment.PROTECTION_FIRE);
|
||||
break;
|
||||
case 16:
|
||||
combined.remove(Enchantment.PROTECTION_PROJECTILE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return combined;
|
||||
@ -258,7 +254,7 @@ public class EventHandlers implements Listener
|
||||
if (Util.isChestPlate(matTwo))
|
||||
return Action.CREATE;
|
||||
|
||||
ArmorTier tier = nbtEditor.getArmorTier(itemOne);
|
||||
ArmorTier tier = NBTEditor.getArmorTier(itemOne);
|
||||
|
||||
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
|
||||
// same tier...
|
||||
if (nbtEditor.getArmorTier(itemTwo) == tier)
|
||||
if (NBTEditor.getArmorTier(itemTwo) == tier)
|
||||
return Action.COMBINE;
|
||||
|
||||
// If the armored elytra is not of the leather tier, but itemTwo is leather,
|
||||
@ -309,47 +305,47 @@ public class EventHandlers implements Listener
|
||||
{
|
||||
Action action = isValidInput(itemA, itemB);
|
||||
ArmorTier newTier = ArmorTier.NONE;
|
||||
ArmorTier curTier = nbtEditor.getArmorTier(itemA);
|
||||
ArmorTier curTier = NBTEditor.getArmorTier(itemA);
|
||||
short durability = 0;
|
||||
Map<Enchantment, Integer> enchantments = itemA.getEnchantments();
|
||||
enchantments = fixEnchantments(enchantments);
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case REPAIR:
|
||||
newTier = curTier;
|
||||
durability = repairItem(itemA.getDurability(), itemB);
|
||||
break;
|
||||
case COMBINE:
|
||||
newTier = curTier;
|
||||
durability = (short) (-itemA.getType().getMaxDurability() - itemA.getDurability()
|
||||
- itemB.getDurability());
|
||||
durability = durability < 0 ? 0 : durability;
|
||||
enchantments = combineEnchantments(enchantments, itemB.getEnchantments());
|
||||
break;
|
||||
case CREATE:
|
||||
newTier = Util.armorToTier(itemB.getType());
|
||||
durability = 0;
|
||||
enchantments = combineEnchantments(enchantments, itemB.getEnchantments());
|
||||
break;
|
||||
case ENCHANT:
|
||||
EnchantmentStorageMeta meta = (EnchantmentStorageMeta) itemB.getItemMeta();
|
||||
newTier = curTier;
|
||||
durability = itemA.getDurability();
|
||||
// If there aren't any illegal enchantments on the book, continue as normal.
|
||||
// Otherwise... Block.
|
||||
if (verifyEnchantments(meta.getStoredEnchants()) != meta.getStoredEnchants().size())
|
||||
{
|
||||
enchantments = combineEnchantments(enchantments, meta.getStoredEnchants());
|
||||
case REPAIR:
|
||||
newTier = curTier;
|
||||
durability = repairItem(itemA.getDurability(), itemB);
|
||||
break;
|
||||
}
|
||||
//$FALL-THROUGH$
|
||||
case BLOCK:
|
||||
event.setResult(null);
|
||||
player.updateInventory();
|
||||
//$FALL-THROUGH$
|
||||
case NONE:
|
||||
return;
|
||||
case COMBINE:
|
||||
newTier = curTier;
|
||||
durability = (short) (-itemA.getType().getMaxDurability() - itemA.getDurability()
|
||||
- itemB.getDurability());
|
||||
durability = durability < 0 ? 0 : durability;
|
||||
enchantments = combineEnchantments(enchantments, itemB.getEnchantments());
|
||||
break;
|
||||
case CREATE:
|
||||
newTier = Util.armorToTier(itemB.getType());
|
||||
durability = 0;
|
||||
enchantments = combineEnchantments(enchantments, itemB.getEnchantments());
|
||||
break;
|
||||
case ENCHANT:
|
||||
EnchantmentStorageMeta meta = (EnchantmentStorageMeta) itemB.getItemMeta();
|
||||
newTier = curTier;
|
||||
durability = itemA.getDurability();
|
||||
// If there aren't any illegal enchantments on the book, continue as normal.
|
||||
// Otherwise... Block.
|
||||
if (verifyEnchantments(meta.getStoredEnchants()) != meta.getStoredEnchants().size())
|
||||
{
|
||||
enchantments = combineEnchantments(enchantments, meta.getStoredEnchants());
|
||||
break;
|
||||
}
|
||||
//$FALL-THROUGH$
|
||||
case BLOCK:
|
||||
event.setResult(null);
|
||||
player.updateInventory();
|
||||
//$FALL-THROUGH$
|
||||
case NONE:
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.playerHasCraftPerm(player, newTier))
|
||||
@ -359,14 +355,14 @@ public class EventHandlers implements Listener
|
||||
result.addUnsafeEnchantments(enchantments);
|
||||
result.setDurability(durability);
|
||||
|
||||
result = nbtEditor.addArmorNBTTags(result, newTier, plugin.getConfigLoader().unbreakable());
|
||||
result = NBTEditor.addArmorNBTTags(result, newTier, plugin.getConfigLoader().unbreakable());
|
||||
event.setResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if either itemA or itemB is unoccupied.
|
||||
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
|
||||
// armored elytra)/
|
||||
event.setResult(null);
|
||||
@ -386,7 +382,6 @@ public class EventHandlers implements Listener
|
||||
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
|
||||
@ -399,6 +394,7 @@ public class EventHandlers implements Listener
|
||||
// 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!");
|
||||
exception.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -407,7 +403,8 @@ public class EventHandlers implements Listener
|
||||
if (slot == 2 && anvilInventory.getItem(0) != null && anvilInventory.getItem(1) != 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 (armortier != ArmorTier.NONE && plugin.playerHasCraftPerm(player, armortier))
|
||||
{
|
||||
@ -415,8 +412,9 @@ public class EventHandlers implements Listener
|
||||
// result.
|
||||
// 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.
|
||||
ItemStack result = nbtEditor.addArmorNBTTags(anvilInventory.getItem(2), armortier,
|
||||
ItemStack result = NBTEditor.addArmorNBTTags(anvilInventory.getItem(2), armortier,
|
||||
plugin.getConfigLoader().unbreakable());
|
||||
|
||||
// Give the result to the player and clear the anvil's inventory.
|
||||
if (e.isShiftClick())
|
||||
{
|
||||
@ -427,6 +425,7 @@ public class EventHandlers implements Listener
|
||||
}
|
||||
else
|
||||
player.setItemOnCursor(result);
|
||||
|
||||
// Clean the anvil's inventory after transferring the items.
|
||||
cleanAnvilInventory.accept(anvilInventory);
|
||||
player.updateInventory();
|
||||
@ -465,15 +464,15 @@ public class EventHandlers implements Listener
|
||||
if (p.getInventory().getChestplate() == null)
|
||||
return;
|
||||
|
||||
if (nbtEditor.getArmorTier(p.getInventory().getChestplate()) == ArmorTier.NONE)
|
||||
if (NBTEditor.getArmorTier(p.getInventory().getChestplate()) == ArmorTier.NONE)
|
||||
return;
|
||||
|
||||
ItemStack elytra = p.getInventory().getChestplate();
|
||||
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)
|
||||
if (cause != DamageCause.DROWNING && cause != DamageCause.STARVATION && cause != DamageCause.SUFFOCATION &&
|
||||
cause != DamageCause.SUICIDE && cause != DamageCause.FLY_INTO_WALL && cause != DamageCause.POISON)
|
||||
{
|
||||
int durability = p.getInventory().getChestplate().getDurability();
|
||||
int maxDurability = p.getInventory().getChestplate().getType().getMaxDurability();
|
||||
@ -510,27 +509,31 @@ public class EventHandlers implements Listener
|
||||
@EventHandler
|
||||
public void onEquip(ArmorEquipEvent e)
|
||||
{
|
||||
if (!e.getType().equals(ArmorType.CHESTPLATE) ||
|
||||
e.getNewArmorPiece() == null ||
|
||||
!e.getNewArmorPiece().getType().equals(Material.ELYTRA) )
|
||||
if (e.getMethod().equals(ArmorEquipEvent.EquipMethod.DEATH) ||
|
||||
e.getMethod().equals(ArmorEquipEvent.EquipMethod.BROKE))
|
||||
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);
|
||||
switch(allowed)
|
||||
switch (allowed)
|
||||
{
|
||||
case ALLOWED:
|
||||
break;
|
||||
case BROKEN:
|
||||
plugin.messagePlayer(e.getPlayer(), plugin.getMyMessages().getString("MESSAGES.RepairNeeded"));
|
||||
e.setCancelled(true);
|
||||
break;
|
||||
case NOPERMISSION:
|
||||
plugin.usageDeniedMessage(e.getPlayer(), armorTier);
|
||||
e.setCancelled(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case ALLOWED:
|
||||
break;
|
||||
case BROKEN:
|
||||
plugin.messagePlayer(e.getPlayer(), plugin.getMyMessages().getString("MESSAGES.RepairNeeded"));
|
||||
e.setCancelled(true);
|
||||
break;
|
||||
case NOPERMISSION:
|
||||
plugin.usageDeniedMessage(e.getPlayer(), armorTier);
|
||||
e.setCancelled(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,16 @@
|
||||
package nl.pim16aap2.armoredElytra.handlers;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerItemDamageEvent;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
|
||||
public class FlyDurabilityHandler implements Listener
|
||||
{
|
||||
private final NBTEditor nbtEditor;
|
||||
|
||||
public FlyDurabilityHandler(NBTEditor nbtEditor)
|
||||
public FlyDurabilityHandler()
|
||||
{
|
||||
this.nbtEditor = nbtEditor;
|
||||
}
|
||||
|
||||
// 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)
|
||||
return;
|
||||
if (!e.getPlayer().isFlying())
|
||||
|
||||
if (!e.getPlayer().isGliding())
|
||||
return;
|
||||
|
||||
if (nbtEditor.getArmorTier(e.getItem()) != ArmorTier.NONE)
|
||||
if (NBTEditor.getArmorTier(e.getItem()) != ArmorTier.NONE)
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
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.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -12,19 +15,13 @@ import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
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
|
||||
{
|
||||
private final ArmoredElytra plugin;
|
||||
private final NBTEditor nbtEditor;
|
||||
|
||||
public Uninstaller(ArmoredElytra plugin, NBTEditor nbtEditor)
|
||||
public Uninstaller(ArmoredElytra plugin)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.nbtEditor = nbtEditor;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public int removeArmoredElytras(Inventory inv)
|
||||
@ -33,7 +30,7 @@ public class Uninstaller implements Listener
|
||||
for (ItemStack is : inv)
|
||||
if (is != null)
|
||||
if (is.getType() == Material.ELYTRA)
|
||||
if (nbtEditor.getArmorTier(is) != ArmorTier.NONE)
|
||||
if (NBTEditor.getArmorTier(is) != ArmorTier.NONE)
|
||||
{
|
||||
inv.remove(is);
|
||||
++count;
|
||||
@ -54,7 +51,8 @@ public class Uninstaller implements Listener
|
||||
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!");
|
||||
plugin.messagePlayer((Player) (event.getPlayer()), ChatColor.RED,
|
||||
"Removed " + removed + " armored elytras from your chest!");
|
||||
}
|
||||
}.runTaskLater(plugin, 20);
|
||||
}
|
||||
@ -71,7 +69,8 @@ public class Uninstaller implements Listener
|
||||
Inventory inv = event.getPlayer().getInventory();
|
||||
int removed = removeArmoredElytras(inv);
|
||||
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);
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
package nl.pim16aap2.armoredElytra.nbtEditor;
|
||||
|
||||
public interface GetArmorValue
|
||||
{
|
||||
public int armorValueFromNBTString(String nbtString);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -1,149 +1,132 @@
|
||||
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.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class NBTEditor
|
||||
{
|
||||
private final ArmoredElytra plugin;
|
||||
private final String NMSbase;
|
||||
private final String CraftBase;
|
||||
private Method asNMSCopy;
|
||||
private Method asBukkitCopy;
|
||||
private Class<?> NMSItemStack;
|
||||
private Class<?> CraftItemStack;
|
||||
private static final String versionString = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||
private static final MinecraftVersion minecraftVersion = MinecraftVersion.get(versionString);
|
||||
private static final String NMSbase = "net.minecraft.server." + versionString + ".";
|
||||
private static final String CraftBase = "org.bukkit.craftbukkit." + versionString + ".";
|
||||
|
||||
private Class<?> NBTTagCompound;
|
||||
private Class<?> NBTTagList;
|
||||
private Class<?> NBTBase;
|
||||
private Class<?> NBTTagString;
|
||||
private Class<?> NBTTagByte;
|
||||
private Class<?> NBTTagInt;
|
||||
private static Method asNMSCopy;
|
||||
private static Method asBukkitCopy;
|
||||
private static Class<?> NMSItemStack;
|
||||
private static Class<?> CraftItemStack;
|
||||
|
||||
private Method hasTag;
|
||||
private Method getTag;
|
||||
private static Class<?> NBTTagCompound;
|
||||
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 Method setCompoundTagList;
|
||||
private static Method setTag;
|
||||
|
||||
private Constructor<?> NBTTagStringCtor;
|
||||
private Constructor<?> NBTTagByteCtor;
|
||||
private Constructor<?> NBTTagIntCtor;
|
||||
private static Method setCompoundByte;
|
||||
private static Method setCompoundTagList;
|
||||
|
||||
private boolean success = false;
|
||||
private GetArmorValue getArmorValue;
|
||||
private static Method getCompoundTagList;
|
||||
private static Method getTagListSize;
|
||||
private static Method getTagListAtIndex;
|
||||
|
||||
public NBTEditor(ArmoredElytra plugin)
|
||||
private static Constructor<?> NBTTagStringCtor;
|
||||
private static Constructor<?> NBTTagByteCtor;
|
||||
private static Constructor<?> NBTTagIntCtor;
|
||||
|
||||
private static boolean success;
|
||||
|
||||
private static Function<String, Integer> getArmorValue;
|
||||
|
||||
|
||||
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 static final Pattern pattern_getDouble = Pattern.compile("[0-9]+.[0-9]+");
|
||||
private static final Pattern pattern_getInt = Pattern.compile("[0-9]+");
|
||||
private static final Pattern pattern_isArmor = Pattern.compile("\"generic.armor\"");
|
||||
|
||||
|
||||
static
|
||||
{
|
||||
this.plugin = plugin;
|
||||
final String versionString = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||
NMSbase = "net.minecraft.server." + versionString + ".";
|
||||
CraftBase = "org.bukkit.craftbukkit." + versionString + ".";
|
||||
|
||||
constructNMSClasses();
|
||||
getTagReadingMethod();
|
||||
}
|
||||
|
||||
private void getTagReadingMethod()
|
||||
{
|
||||
if (!success)
|
||||
return;
|
||||
|
||||
String version;
|
||||
try
|
||||
{
|
||||
version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
}
|
||||
catch (final ArrayIndexOutOfBoundsException useAVersionMentionedInTheDescriptionPleaseException)
|
||||
{
|
||||
if (minecraftVersion == null)
|
||||
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
|
||||
getArmorValue = new GetArmorValueNew(plugin);
|
||||
}
|
||||
|
||||
public boolean succes()
|
||||
{
|
||||
return success;
|
||||
}
|
||||
|
||||
private void constructNMSClasses()
|
||||
{
|
||||
try
|
||||
{
|
||||
NMSItemStack = getNMSClass("ItemStack");
|
||||
hasTag = NMSItemStack.getMethod("hasTag");
|
||||
getTag = NMSItemStack.getMethod("getTag");
|
||||
|
||||
CraftItemStack = getCraftClass("inventory.CraftItemStack");
|
||||
asNMSCopy = CraftItemStack.getMethod("asNMSCopy", ItemStack.class);
|
||||
asBukkitCopy = CraftItemStack.getMethod("asBukkitCopy", NMSItemStack);
|
||||
|
||||
NBTBase = getNMSClass("NBTBase");
|
||||
|
||||
NBTTagString = getNMSClass("NBTTagString");
|
||||
NBTTagStringCtor = NBTTagString.getDeclaredConstructor(String.class);
|
||||
NBTTagStringCtor.setAccessible(true);
|
||||
|
||||
NBTTagByte = getNMSClass("NBTTagByte");
|
||||
NBTTagByteCtor = NBTTagByte.getDeclaredConstructor(byte.class);
|
||||
NBTTagByteCtor.setAccessible(true);
|
||||
|
||||
NBTTagInt = getNMSClass("NBTTagInt");
|
||||
NBTTagIntCtor = NBTTagInt.getDeclaredConstructor(int.class);
|
||||
NBTTagIntCtor.setAccessible(true);
|
||||
|
||||
NBTTagCompound = getNMSClass("NBTTagCompound");
|
||||
setTag = NBTTagCompound.getMethod("set", String.class, NBTBase);
|
||||
|
||||
NBTTagList = getNMSClass("NBTTagList");
|
||||
// Starting in 1.14, you also need to provide an int value when adding nbt tags.
|
||||
try
|
||||
{
|
||||
addCompound = NBTTagList.getMethod("add", NBTBase);
|
||||
// 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");
|
||||
hasTag = NMSItemStack.getMethod("hasTag");
|
||||
getTag = NMSItemStack.getMethod("getTag");
|
||||
|
||||
CraftItemStack = getCraftClass("inventory.CraftItemStack");
|
||||
asNMSCopy = CraftItemStack.getMethod("asNMSCopy", ItemStack.class);
|
||||
asBukkitCopy = CraftItemStack.getMethod("asBukkitCopy", NMSItemStack);
|
||||
|
||||
NBTBase = getNMSClass("NBTBase");
|
||||
|
||||
NBTTagString = getNMSClass("NBTTagString");
|
||||
NBTTagStringCtor = NBTTagString.getDeclaredConstructor(String.class);
|
||||
NBTTagStringCtor.setAccessible(true);
|
||||
|
||||
NBTTagByte = getNMSClass("NBTTagByte");
|
||||
NBTTagByteCtor = NBTTagByte.getDeclaredConstructor(byte.class);
|
||||
NBTTagByteCtor.setAccessible(true);
|
||||
|
||||
NBTTagInt = getNMSClass("NBTTagInt");
|
||||
NBTTagIntCtor = NBTTagInt.getDeclaredConstructor(int.class);
|
||||
NBTTagIntCtor.setAccessible(true);
|
||||
|
||||
NBTTagCompound = getNMSClass("NBTTagCompound");
|
||||
setTag = NBTTagCompound.getMethod("set", String.class, NBTBase);
|
||||
|
||||
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.
|
||||
try
|
||||
{
|
||||
addCompound = NBTTagList.getMethod("add", NBTBase);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
addCompound = NBTTagList.getMethod("add", int.class, NBTBase);
|
||||
}
|
||||
|
||||
setCompoundTagList = NBTTagCompound.getMethod("set", String.class, NBTBase);
|
||||
setCompoundByte = NBTTagCompound.getMethod("set", String.class, NBTBase);
|
||||
getCompoundTagList = NBTTagCompound.getMethod("getList", String.class, int.class);
|
||||
|
||||
success = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (NoSuchMethodException | SecurityException | ClassNotFoundException e)
|
||||
{
|
||||
addCompound = NBTTagList.getMethod("add", int.class, NBTBase);
|
||||
e.printStackTrace();
|
||||
success = false;
|
||||
}
|
||||
|
||||
setCompoundTagList = NBTTagCompound.getMethod("set", String.class, NBTBase);
|
||||
setCompoundByte = NBTTagCompound.getMethod("set", String.class, NBTBase);
|
||||
|
||||
success = true;
|
||||
}
|
||||
catch (NoSuchMethodException | SecurityException | ClassNotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void addCompound(Object instance, Object nbtbase)
|
||||
private static void addCompound(Object instance, Object nbtbase)
|
||||
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
|
||||
{
|
||||
if (addCompound.getParameterCount() == 2)
|
||||
@ -153,7 +136,7 @@ public class NBTEditor
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
@ -161,15 +144,17 @@ public class NBTEditor
|
||||
int armorProtection = ArmorTier.getArmor(armorTier);
|
||||
int armorToughness = ArmorTier.getToughness(armorTier);
|
||||
|
||||
itemmeta.setDisplayName(plugin.getArmoredElytraName(armorTier));
|
||||
if (plugin.getElytraLore() != null)
|
||||
itemmeta.setDisplayName(ArmoredElytra.getInstance().getArmoredElytraName(armorTier));
|
||||
if (ArmoredElytra.getInstance().getElytraLore() != null)
|
||||
itemmeta
|
||||
.setLore(Arrays.asList(plugin.fillInArmorTierInStringNoColor(plugin.getElytraLore(), armorTier)));
|
||||
.setLore(Arrays.asList(ArmoredElytra.getInstance().fillInArmorTierInStringNoColor(
|
||||
ArmoredElytra.getInstance().getElytraLore(), armorTier)));
|
||||
|
||||
item.setItemMeta(itemmeta);
|
||||
|
||||
Object nmsStack = asNMSCopy.invoke(null, item);
|
||||
Object compound = ((boolean) hasTag.invoke(nmsStack) ? getTag.invoke(nmsStack) :
|
||||
NBTTagCompound.newInstance());
|
||||
NBTTagCompound.newInstance());
|
||||
Object modifiers = NBTTagList.newInstance();
|
||||
Object armor = NBTTagCompound.newInstance(); // I should be able to simply add custom tags here!
|
||||
setTag.invoke(armor, "AttributeName", NBTTagStringCtor.newInstance("generic.armor"));
|
||||
@ -196,60 +181,195 @@ public class NBTEditor
|
||||
|
||||
setCompoundTagList.invoke(compound, "AttributeModifiers", modifiers);
|
||||
item = (ItemStack) asBukkitCopy.invoke(null, nmsStack);
|
||||
|
||||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e)
|
||||
{
|
||||
// TODO: Log this or something. Pretty serious issue for a plugin based entirely
|
||||
// on this code.
|
||||
e.printStackTrace();
|
||||
}
|
||||
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
|
||||
{
|
||||
if (item == null)
|
||||
return ArmorTier.NONE;
|
||||
if (item.getType() != Material.ELYTRA)
|
||||
return ArmorTier.NONE;
|
||||
return (int) Double.parseDouble(getArmorAmount(string, pattern_findAmount_double, pattern_getDouble));
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
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));
|
||||
if (compound == null)
|
||||
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)
|
||||
{
|
||||
case 3:
|
||||
return ArmorTier.LEATHER;
|
||||
case 5:
|
||||
return ArmorTier.GOLD;
|
||||
case 6:
|
||||
return ArmorTier.IRON;
|
||||
case 8:
|
||||
return ArmorTier.DIAMOND;
|
||||
default:
|
||||
return ArmorTier.NONE;
|
||||
// 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:
|
||||
return ArmorTier.LEATHER;
|
||||
case 5:
|
||||
return ArmorTier.GOLD;
|
||||
case 6:
|
||||
return ArmorTier.IRON;
|
||||
case 8:
|
||||
return ArmorTier.DIAMOND;
|
||||
default:
|
||||
return ArmorTier.NONE;
|
||||
}
|
||||
}
|
||||
return ArmorTier.NONE;
|
||||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
private Class<?> getCraftClass(String name) throws ClassNotFoundException
|
||||
private static Class<?> getCraftClass(String name)
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user