Clean up code, fix bugs, use Maven
- Switched to Maven for project compilation. - Added config options to globally bypass permissions for crafting and/or wearing of all tiers. - Now using Consumer for stuff that previously used the ugly is1_9 boolean. - Switched to using ArmorEquipEvent for checking if players are allowed to wear something. It's much cleaner and includes some previously omitted equip events (such as from a dispenser). - Code cleanup. - Fixed issue where unbreakable armored elytras would still "break". - Added MENDING enchantment to the default set of enchantments again. - Using Maven shade for bStats and removed the old Metrics class.
This commit is contained in:
parent
080b6c6dab
commit
e906ddfdb3
160
pom.xml
160
pom.xml
@ -1,21 +1,27 @@
|
|||||||
<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">
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
<modelVersion>4.0.0</modelVersion>
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
<groupId>nl.pim16aap2</groupId>
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<artifactId>ArmoredElytra</artifactId>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<version>2.4.8-SNAPSHOT</version>
|
<groupId>nl.pim16aap2</groupId>
|
||||||
|
<artifactId>ArmoredElytra</artifactId>
|
||||||
|
<version>2.4.10</version>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<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>
|
||||||
<repository>
|
<repository>
|
||||||
<id>bstats-repo</id>
|
<id>CodeMC</id>
|
||||||
<url>http://repo.bstats.org/content/repositories/releases/</url>
|
<url>https://repo.codemc.org/repository/maven-public</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
<repository>
|
||||||
|
<id>jitpack.io</id>
|
||||||
|
<url>https://jitpack.io</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
<artifactId>spigot</artifactId>
|
<artifactId>spigot</artifactId>
|
||||||
@ -23,24 +29,108 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!--bStats -->
|
<dependency>
|
||||||
<dependency>
|
<groupId>com.github.tr7zw</groupId>
|
||||||
<groupId>org.bstats</groupId>
|
<artifactId>Item-NBT-API</artifactId>
|
||||||
<artifactId>bstats-bukkit</artifactId>
|
<version>master-SNAPSHOT</version>
|
||||||
<version>1.2</version>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
<!--bStats -->
|
||||||
<plugins>
|
<dependency>
|
||||||
<plugin>
|
<groupId>org.bstats</groupId>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<artifactId>bstats-bukkit</artifactId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<version>1.5</version>
|
||||||
<configuration>
|
<scope>compile</scope>
|
||||||
<source>1.8</source>
|
</dependency>
|
||||||
<target>1.8</target>
|
|
||||||
</configuration>
|
<!--
|
||||||
</plugin>
|
<dependency>
|
||||||
</plugins>
|
<groupId>com.github.Arnuh</groupId>
|
||||||
</build>
|
<artifactId>ArmorEquipEvent</artifactId>
|
||||||
|
<version>39fadc1393</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
-->
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>${project.name}</finalName>
|
||||||
|
<sourceDirectory>src</sourceDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src</directory>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</resource>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<includes>
|
||||||
|
<include>plugin.yml</include>
|
||||||
|
<include>config.yml</include>
|
||||||
|
<include>en_US.txt</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>3.2.1</version>
|
||||||
|
<configuration>
|
||||||
|
<relocations>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.bstats</pattern>
|
||||||
|
<shadedPattern>nl.pim16aap2.armoredElytra</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<!--<relocation>
|
||||||
|
<pattern>com.codingforcookies</pattern>
|
||||||
|
<shadedPattern>nl.pim16aap2.armoredElytra</shadedPattern>
|
||||||
|
</relocation>-->
|
||||||
|
</relocations>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>8</source>
|
||||||
|
<target>8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
<version>1.8</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>deploy-artifact</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>run</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<target>
|
||||||
|
<ant antfile="${basedir}/mover.xml">
|
||||||
|
<target name="copyAll" />
|
||||||
|
</ant>
|
||||||
|
</target>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -3,6 +3,7 @@ package nl.pim16aap2.armoredElytra;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.bstats.bukkit.Metrics;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -19,9 +20,13 @@ import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
|||||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||||
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.Metrics;
|
|
||||||
import nl.pim16aap2.armoredElytra.util.Update;
|
import nl.pim16aap2.armoredElytra.util.Update;
|
||||||
|
|
||||||
|
// 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: Verify enchantments on startup. Remove them from the list if they're invalid.
|
||||||
|
// TODO: Don't delete the config file. Look at BigDoors.
|
||||||
|
|
||||||
public class ArmoredElytra extends JavaPlugin implements Listener
|
public class ArmoredElytra extends JavaPlugin implements Listener
|
||||||
{
|
{
|
||||||
private NBTEditor nbtEditor;
|
private NBTEditor nbtEditor;
|
||||||
@ -151,6 +156,16 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
|||||||
elytraLore = (Objects.equals(elytraLore, new String("NONE")) ? null : elytraLore );
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean playerHasWearPerm(Player player, ArmorTier 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.
|
||||||
public boolean isUpToDate()
|
public boolean isUpToDate()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ 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;
|
private final NBTEditor nbtEditor;
|
||||||
|
|
||||||
public CommandHandler(ArmoredElytra plugin, NBTEditor nbtEditor)
|
public CommandHandler(ArmoredElytra plugin, NBTEditor nbtEditor)
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package nl.pim16aap2.armoredElytra.handlers;
|
package nl.pim16aap2.armoredElytra.handlers;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -13,14 +16,16 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
|
||||||
import org.bukkit.event.inventory.InventoryType;
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
import org.bukkit.event.inventory.PrepareAnvilEvent;
|
import org.bukkit.event.inventory.PrepareAnvilEvent;
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
import org.bukkit.inventory.AnvilInventory;
|
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 org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
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.ArmoredElytra;
|
||||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||||
@ -32,48 +37,74 @@ import nl.pim16aap2.armoredElytra.util.XMaterial;
|
|||||||
|
|
||||||
public class EventHandlers implements Listener
|
public class EventHandlers implements Listener
|
||||||
{
|
{
|
||||||
private final NBTEditor nbtEditor;
|
private final NBTEditor nbtEditor;
|
||||||
private final ArmoredElytra plugin;
|
private final ArmoredElytra plugin;
|
||||||
private final boolean is1_9;
|
|
||||||
|
private final Consumer<AnvilInventory> cleanAnvilInventory;
|
||||||
|
private final Consumer<Player> moveChestplateToInventory;
|
||||||
|
|
||||||
public EventHandlers(ArmoredElytra plugin, NBTEditor nbtEditor, boolean is1_9)
|
public EventHandlers(ArmoredElytra plugin, NBTEditor nbtEditor, boolean is1_9)
|
||||||
{
|
{
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.nbtEditor = nbtEditor;
|
this.nbtEditor = nbtEditor;
|
||||||
this.is1_9 = is1_9;
|
initializeArmorEquipEvent();
|
||||||
}
|
|
||||||
|
|
||||||
// Remove item from player's chestplate slot and puts it in their normal inventory.
|
|
||||||
private void unenquipChestPlayer(Player p)
|
|
||||||
{
|
|
||||||
if (is1_9)
|
|
||||||
p.getInventory().getChestplate().setType(XMaterial.AIR.parseMaterial());
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p.getInventory().addItem(p.getInventory().getChestplate());
|
|
||||||
p.getInventory().getChestplate().setAmount(0);
|
|
||||||
p.updateInventory();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the anvil's inventory (destroy all the items in all 3 slots (second slot is not emptied, when repairing you can safely give multiple items)).
|
|
||||||
private void cleanAnvil(AnvilInventory anvilInventory)
|
|
||||||
{
|
|
||||||
if (is1_9)
|
if (is1_9)
|
||||||
{
|
{
|
||||||
ItemStack air = new ItemStack(XMaterial.AIR.parseMaterial(), 1);
|
cleanAnvilInventory = this::cleanAnvilOld;
|
||||||
anvilInventory.setItem(0, air);
|
moveChestplateToInventory = this::moveChestplateToInventoryOld;
|
||||||
anvilInventory.setItem(1, air);
|
|
||||||
anvilInventory.setItem(2, air);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
anvilInventory.getItem(0).setAmount(0);
|
cleanAnvilInventory = this::cleanAnvilNew;
|
||||||
anvilInventory.getItem(1).setAmount(anvilInventory.getItem(1).getAmount() - 1);
|
moveChestplateToInventory = this::moveChestplateToInventoryNew;
|
||||||
anvilInventory.getItem(2).setAmount(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initializeArmorEquipEvent()
|
||||||
|
{
|
||||||
|
Bukkit.getPluginManager().registerEvents(new ArmorListener(new ArrayList<String>()), plugin);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Older versions did not have this event. So try to load it if possible, but
|
||||||
|
// don't worry
|
||||||
|
// about it not working.
|
||||||
|
Class.forName("org.bukkit.event.block.BlockDispenseArmorEvent");
|
||||||
|
plugin.getServer().getPluginManager().registerEvents(new DispenserArmorListener(), plugin);
|
||||||
|
}
|
||||||
|
catch (Exception ignored)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveChestplateToInventoryOld(Player player)
|
||||||
|
{
|
||||||
|
player.getInventory().getChestplate().setType(XMaterial.AIR.parseMaterial());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveChestplateToInventoryNew(Player player)
|
||||||
|
{
|
||||||
|
player.getInventory().addItem(player.getInventory().getChestplate());
|
||||||
|
player.getInventory().getChestplate().setAmount(0);
|
||||||
|
player.updateInventory();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean 1.9 inventories.
|
||||||
|
private void cleanAnvilOld(AnvilInventory anvilInventory)
|
||||||
|
{
|
||||||
|
ItemStack air = new ItemStack(XMaterial.AIR.parseMaterial(), 1);
|
||||||
|
anvilInventory.setItem(0, air);
|
||||||
|
anvilInventory.setItem(1, air);
|
||||||
|
anvilInventory.setItem(2, air);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean >=1.10 inventories.
|
||||||
|
private void cleanAnvilNew(AnvilInventory anvilInventory)
|
||||||
|
{
|
||||||
|
anvilInventory.getItem(0).setAmount(0);
|
||||||
|
anvilInventory.getItem(1).setAmount(anvilInventory.getItem(1).getAmount() - 1);
|
||||||
|
anvilInventory.getItem(2).setAmount(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the enchantment is allowed on elytras.
|
// Check if the enchantment is allowed on elytras.
|
||||||
private boolean isAllowedEnchantment(Enchantment enchant)
|
private boolean isAllowedEnchantment(Enchantment enchant)
|
||||||
{
|
{
|
||||||
@ -85,18 +116,20 @@ public class EventHandlers implements Listener
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Combine 2 maps of enchantments (and remove any invalid ones).
|
// Combine 2 maps of enchantments (and remove any invalid ones).
|
||||||
private Map<Enchantment, Integer> combineEnchantments(Map<Enchantment, Integer> enchantments0, Map<Enchantment, Integer> enchantments1)
|
private Map<Enchantment, Integer> combineEnchantments(Map<Enchantment, Integer> enchantments0,
|
||||||
|
Map<Enchantment, Integer> enchantments1)
|
||||||
{
|
{
|
||||||
enchantments0 = fixEnchantments(enchantments0);
|
enchantments0 = fixEnchantments(enchantments0);
|
||||||
Map<Enchantment, Integer> combined = new HashMap<>(fixEnchantments(enchantments0));
|
Map<Enchantment, Integer> combined = new HashMap<>(fixEnchantments(enchantments0));
|
||||||
|
|
||||||
// If the second set of enchantments is null, the combined enchantments are just the first enchantments.
|
// If the second set of enchantments is null, the combined enchantments are just
|
||||||
|
// the first enchantments.
|
||||||
if (enchantments1 == null)
|
if (enchantments1 == null)
|
||||||
return combined;
|
return combined;
|
||||||
|
|
||||||
enchantments1 = fixEnchantments(enchantments1);
|
enchantments1 = fixEnchantments(enchantments1);
|
||||||
// Loop through the enchantments of item1.
|
// Loop through the enchantments of item1.
|
||||||
for (Map.Entry<Enchantment, Integer > entry : enchantments1.entrySet())
|
for (Map.Entry<Enchantment, Integer> entry : enchantments1.entrySet())
|
||||||
{
|
{
|
||||||
Integer enchantLevel = enchantments0.get(entry.getKey());
|
Integer enchantLevel = enchantments0.get(entry.getKey());
|
||||||
if (enchantLevel != null)
|
if (enchantLevel != null)
|
||||||
@ -123,11 +156,13 @@ public class EventHandlers implements Listener
|
|||||||
int protVal0 = Util.getProtectionEnchantmentsVal(enchantments0);
|
int protVal0 = Util.getProtectionEnchantmentsVal(enchantments0);
|
||||||
int protVal1 = Util.getProtectionEnchantmentsVal(enchantments1);
|
int protVal1 = Util.getProtectionEnchantmentsVal(enchantments1);
|
||||||
|
|
||||||
// If they have different protection enchantments, keep enchantment1's enchantments
|
// If they have different protection enchantments, keep enchantment1's
|
||||||
// And remove the protection enchantment from enchantments0. Yes, this system only works
|
// enchantments
|
||||||
|
// And remove the protection enchantment from enchantments0. Yes, this system
|
||||||
|
// only works
|
||||||
// If there is 1 protection enchantment on
|
// If there is 1 protection enchantment on
|
||||||
if (protVal0 != 0 && protVal1 != 0 && protVal0 != protVal1)
|
if (protVal0 != 0 && protVal1 != 0 && protVal0 != protVal1)
|
||||||
switch(protVal0)
|
switch (protVal0)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
combined.remove(Enchantment.PROTECTION_ENVIRONMENTAL);
|
combined.remove(Enchantment.PROTECTION_ENVIRONMENTAL);
|
||||||
@ -154,7 +189,7 @@ public class EventHandlers implements Listener
|
|||||||
{
|
{
|
||||||
// Get the multiplier for the repair items.
|
// Get the multiplier for the repair items.
|
||||||
double mult = 0.01;
|
double mult = 0.01;
|
||||||
if ( repairItem.getType().equals(Material.LEATHER))
|
if (repairItem.getType().equals(Material.LEATHER))
|
||||||
mult *= (100.0f / plugin.getConfigLoader().LEATHER_TO_FULL());
|
mult *= (100.0f / plugin.getConfigLoader().LEATHER_TO_FULL());
|
||||||
|
|
||||||
else if (repairItem.getType().equals(Material.GOLD_INGOT))
|
else if (repairItem.getType().equals(Material.GOLD_INGOT))
|
||||||
@ -191,18 +226,16 @@ public class EventHandlers implements Listener
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Valid inputs:
|
||||||
* Valid inputs:
|
// - Elytra (armored or not) + chestplate -> Create Armored Elytra
|
||||||
* - Elytra (armored or not) + chestplate -> Create Armored Elytra
|
// - Elytra (armored) + enchanted book -> Enchant
|
||||||
* - Elytra (armored) + enchanted book -> Enchant
|
// - Elytra (armored) + its repair item -> Repair
|
||||||
* - Elytra (armored) + its repair item -> Repair
|
// - Elytra (armored) + other elytra (armored) -> Combine (Enchant + Repair)
|
||||||
* - Elytra (armored) + other elytra (armored) -> Combine (Enchant + Repair)
|
// ! Elytra (armored, !leather) + leather -> Block
|
||||||
* ! Elytra (armored, !leather) + leather -> Block
|
//
|
||||||
*
|
// Ignoring:
|
||||||
* Ignoring:
|
// - Elytra (not armored) + !chestplate -> None
|
||||||
* - Elytra (not armored) + !chestplate -> None
|
// - * + * -> None
|
||||||
* - * + * -> None
|
|
||||||
*/
|
|
||||||
private Action isValidInput(ItemStack itemOne, ItemStack itemTwo)
|
private Action isValidInput(ItemStack itemOne, ItemStack itemTwo)
|
||||||
{
|
{
|
||||||
if (itemOne == null || itemTwo == null)
|
if (itemOne == null || itemTwo == null)
|
||||||
@ -212,8 +245,8 @@ public class EventHandlers implements Listener
|
|||||||
if (itemTwo.getType() == Material.ELYTRA && itemOne.getType() != Material.ELYTRA)
|
if (itemTwo.getType() == Material.ELYTRA && itemOne.getType() != Material.ELYTRA)
|
||||||
{
|
{
|
||||||
ItemStack tmp = itemOne;
|
ItemStack tmp = itemOne;
|
||||||
itemOne = itemTwo;
|
itemOne = itemTwo;
|
||||||
itemTwo = tmp;
|
itemTwo = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemOne.getType() != Material.ELYTRA)
|
if (itemOne.getType() != Material.ELYTRA)
|
||||||
@ -237,7 +270,8 @@ public class EventHandlers implements Listener
|
|||||||
if (ArmorTier.getRepairItem(tier) == matTwo)
|
if (ArmorTier.getRepairItem(tier) == matTwo)
|
||||||
return Action.REPAIR;
|
return Action.REPAIR;
|
||||||
|
|
||||||
// If the armored elytra is to be combined with another armored elytra of the same tier...
|
// 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;
|
return Action.COMBINE;
|
||||||
|
|
||||||
@ -254,9 +288,9 @@ public class EventHandlers implements Listener
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
private void onAnvilInventoryOpen(PrepareAnvilEvent event)
|
private void onAnvilInventoryOpen(PrepareAnvilEvent event)
|
||||||
{
|
{
|
||||||
Player player = (Player) event.getView().getPlayer();
|
Player player = (Player) event.getView().getPlayer();
|
||||||
ItemStack itemA = event.getInventory().getItem(0);
|
ItemStack itemA = event.getInventory().getItem(0);
|
||||||
ItemStack itemB = event.getInventory().getItem(1);
|
ItemStack itemB = event.getInventory().getItem(1);
|
||||||
ItemStack result = null;
|
ItemStack result = null;
|
||||||
|
|
||||||
if (itemA != null && itemB != null)
|
if (itemA != null && itemB != null)
|
||||||
@ -264,42 +298,43 @@ public class EventHandlers implements Listener
|
|||||||
if (itemB.getType() == Material.ELYTRA && itemA.getType() != Material.ELYTRA)
|
if (itemB.getType() == Material.ELYTRA && itemA.getType() != Material.ELYTRA)
|
||||||
{
|
{
|
||||||
result = itemA;
|
result = itemA;
|
||||||
itemA = itemB;
|
itemA = itemB;
|
||||||
itemB = result;
|
itemB = result;
|
||||||
result = null;
|
result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if there are items in both input slots.
|
// Check if there are items in both input slots.
|
||||||
if (itemA != null && itemB != null)
|
if (itemA != null && itemB != null)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case REPAIR:
|
case REPAIR:
|
||||||
newTier = curTier;
|
newTier = curTier;
|
||||||
durability = repairItem(itemA.getDurability(), itemB);
|
durability = repairItem(itemA.getDurability(), itemB);
|
||||||
break;
|
break;
|
||||||
case COMBINE:
|
case COMBINE:
|
||||||
newTier = curTier;
|
newTier = curTier;
|
||||||
durability = (short) (- itemA.getType().getMaxDurability() - itemA.getDurability() - itemB.getDurability());
|
durability = (short) (-itemA.getType().getMaxDurability() - itemA.getDurability()
|
||||||
durability = durability < 0 ? 0 : durability;
|
- itemB.getDurability());
|
||||||
enchantments = combineEnchantments(enchantments, itemB.getEnchantments());
|
durability = durability < 0 ? 0 : durability;
|
||||||
|
enchantments = combineEnchantments(enchantments, itemB.getEnchantments());
|
||||||
break;
|
break;
|
||||||
case CREATE:
|
case CREATE:
|
||||||
newTier = Util.armorToTier(itemB.getType());
|
newTier = Util.armorToTier(itemB.getType());
|
||||||
durability = 0;
|
durability = 0;
|
||||||
enchantments = combineEnchantments(enchantments, itemB.getEnchantments());
|
enchantments = combineEnchantments(enchantments, itemB.getEnchantments());
|
||||||
break;
|
break;
|
||||||
case ENCHANT:
|
case ENCHANT:
|
||||||
EnchantmentStorageMeta meta = (EnchantmentStorageMeta) itemB.getItemMeta();
|
EnchantmentStorageMeta meta = (EnchantmentStorageMeta) itemB.getItemMeta();
|
||||||
newTier = curTier;
|
newTier = curTier;
|
||||||
durability = itemA.getDurability();
|
durability = itemA.getDurability();
|
||||||
// If there aren't any illegal enchantments on the book, continue as normal.
|
// If there aren't any illegal enchantments on the book, continue as normal.
|
||||||
// Otherwise... Block.
|
// Otherwise... Block.
|
||||||
if (verifyEnchantments(meta.getStoredEnchants()) != meta.getStoredEnchants().size())
|
if (verifyEnchantments(meta.getStoredEnchants()) != meta.getStoredEnchants().size())
|
||||||
@ -316,7 +351,7 @@ public class EventHandlers implements Listener
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Util.playerHasCraftPerm(player, newTier))
|
if (plugin.playerHasCraftPerm(player, newTier))
|
||||||
{
|
{
|
||||||
result = new ItemStack(Material.ELYTRA, 1);
|
result = new ItemStack(Material.ELYTRA, 1);
|
||||||
if (enchantments != null)
|
if (enchantments != null)
|
||||||
@ -329,8 +364,10 @@ public class EventHandlers implements Listener
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if either itemA or itemB is unoccupied.
|
// Check if either itemA or itemB is unoccupied.
|
||||||
if ((itemA == null || itemB == null) && nbtEditor.getArmorTier(event.getInventory().getItem(2)) != ArmorTier.NONE)
|
if ((itemA == null || itemB == null) &&
|
||||||
// If Item2 is occupied despite itemA or itemB not being occupied. (only for armored elytra)/
|
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);
|
event.setResult(null);
|
||||||
player.updateInventory();
|
player.updateInventory();
|
||||||
}
|
}
|
||||||
@ -357,22 +394,28 @@ public class EventHandlers implements Listener
|
|||||||
}
|
}
|
||||||
catch (ClassCastException exception)
|
catch (ClassCastException exception)
|
||||||
{
|
{
|
||||||
// Print warning to console and exit onInventoryClick event (no support for custom inventories as they are usually used for GUI's).
|
// Print warning to console and exit onInventoryClick event (no support for
|
||||||
plugin.debugMsg(Level.WARNING, "Could not cast inventory to anvilInventory for player " + player.getName() + "! Armored Elytras cannot be crafted!");
|
// 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!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int slot = e.getRawSlot();
|
int slot = e.getRawSlot();
|
||||||
|
|
||||||
if (slot == 2 && anvilInventory.getItem(0) != null && anvilInventory.getItem(1) != null && anvilInventory.getItem(2) != null)
|
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 there's an armored elytra in the final slot...
|
||||||
if (armortier != ArmorTier.NONE && Util.playerHasCraftPerm(player, armortier))
|
if (armortier != ArmorTier.NONE && plugin.playerHasCraftPerm(player, armortier))
|
||||||
{
|
{
|
||||||
// Create a new armored elytra and give that one to the player instead of the result.
|
// Create a new armored elytra and give that one to the player instead of the
|
||||||
// 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.
|
// result.
|
||||||
ItemStack result = nbtEditor.addArmorNBTTags(anvilInventory.getItem(2), armortier, plugin.getConfigLoader().unbreakable());
|
// 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,
|
||||||
|
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())
|
||||||
{
|
{
|
||||||
@ -384,98 +427,34 @@ 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.
|
||||||
cleanAnvil(anvilInventory);
|
cleanAnvilInventory.accept(anvilInventory);
|
||||||
player.updateInventory();
|
player.updateInventory();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the player has the correct permission and that the item is not broken.
|
// Make sure the player has the correct permission and that the item is not
|
||||||
|
// broken.
|
||||||
private AllowedToWearEnum isAllowedToWear(ItemStack elytra, Player player, ArmorTier armorTier)
|
private AllowedToWearEnum isAllowedToWear(ItemStack elytra, Player player, ArmorTier armorTier)
|
||||||
{
|
{
|
||||||
|
if (armorTier.equals(ArmorTier.NONE))
|
||||||
|
return AllowedToWearEnum.ALLOWED;
|
||||||
if (Util.isBroken(elytra))
|
if (Util.isBroken(elytra))
|
||||||
return AllowedToWearEnum.BROKEN;
|
return AllowedToWearEnum.BROKEN;
|
||||||
if (!Util.playerHasWearPerm(player, armorTier))
|
if (!plugin.playerHasWearPerm(player, armorTier))
|
||||||
return AllowedToWearEnum.NOPERMISSION;
|
return AllowedToWearEnum.NOPERMISSION;
|
||||||
return AllowedToWearEnum.ALLOWED;
|
return AllowedToWearEnum.ALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the player tries to equip armor by richt clicking it.
|
// Handle armored elytra durability loss.
|
||||||
@EventHandler
|
|
||||||
public void onRightClick(PlayerInteractEvent event)
|
|
||||||
{
|
|
||||||
if (!event.getAction().equals(org.bukkit.event.block.Action.RIGHT_CLICK_AIR) &&
|
|
||||||
!event.getAction().equals(org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK))
|
|
||||||
return;
|
|
||||||
|
|
||||||
ItemStack item = event.getItem();
|
|
||||||
if (item == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
|
|
||||||
if (item.getType() == Material.ELYTRA)
|
|
||||||
{
|
|
||||||
ArmorTier armorTier = nbtEditor.getArmorTier(item);
|
|
||||||
if (nbtEditor.getArmorTier(item) == ArmorTier.NONE)
|
|
||||||
return;
|
|
||||||
AllowedToWearEnum allowed = isAllowedToWear(item, player, armorTier);
|
|
||||||
if (allowed == AllowedToWearEnum.BROKEN)
|
|
||||||
{
|
|
||||||
plugin.messagePlayer(player, plugin.getMyMessages().getString("MESSAGES.RepairNeeded"));
|
|
||||||
event.setCancelled(true);
|
|
||||||
player.updateInventory();
|
|
||||||
}
|
|
||||||
else if (allowed == AllowedToWearEnum.NOPERMISSION)
|
|
||||||
{
|
|
||||||
plugin.usageDeniedMessage(player, armorTier);
|
|
||||||
event.setCancelled(true);
|
|
||||||
player.updateInventory();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Player closes their inventory. Also checks for whether they are allowed to wear the armored elytra they are wearing.
|
|
||||||
// This is done again here because there are ways to bypass permission check when equipping.
|
|
||||||
@EventHandler
|
|
||||||
public void onInventoryClose(InventoryCloseEvent e)
|
|
||||||
{
|
|
||||||
verifyArmorInChestSlot((Player) e.getPlayer());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the player is allowed to wear the armored elytra based on their permissions.
|
|
||||||
private void verifyArmorInChestSlot(Player player)
|
|
||||||
{
|
|
||||||
ItemStack chestplate = player.getInventory().getChestplate();
|
|
||||||
// If the player equips a new chestplate.
|
|
||||||
if (player.getInventory().getChestplate() == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ArmorTier armorTier = nbtEditor.getArmorTier(chestplate);
|
|
||||||
// If that chestplate is an (armored) elytra.
|
|
||||||
if (armorTier == ArmorTier.NONE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
AllowedToWearEnum allowed = isAllowedToWear(chestplate, player, armorTier);
|
|
||||||
if (allowed == AllowedToWearEnum.BROKEN)
|
|
||||||
{
|
|
||||||
plugin.messagePlayer(player, plugin.getMyMessages().getString("MESSAGES.RepairNeeded"));
|
|
||||||
unenquipChestPlayer(player);
|
|
||||||
}
|
|
||||||
else if (allowed == AllowedToWearEnum.NOPERMISSION)
|
|
||||||
{
|
|
||||||
plugin.usageDeniedMessage(player, armorTier);
|
|
||||||
unenquipChestPlayer(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Because the armored elytra doesn't actually give any armor, the damage
|
|
||||||
// received by players wearing an armored elytra is calculated here.
|
|
||||||
@EventHandler(ignoreCancelled = true)
|
@EventHandler(ignoreCancelled = true)
|
||||||
public void onPlayerDamage(EntityDamageEvent e)
|
public void onPlayerDamage(EntityDamageEvent e)
|
||||||
{
|
{
|
||||||
if(!(e.getEntity() instanceof Player))
|
if (!(e.getEntity() instanceof Player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (plugin.getConfigLoader().unbreakable())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Player p = (Player) e.getEntity();
|
Player p = (Player) e.getEntity();
|
||||||
@ -495,21 +474,24 @@ public class EventHandlers implements Listener
|
|||||||
if (cause != DamageCause.DROWNING && cause != DamageCause.STARVATION && cause != DamageCause.SUFFOCATION &&
|
if (cause != DamageCause.DROWNING && cause != DamageCause.STARVATION && cause != DamageCause.SUFFOCATION &&
|
||||||
cause != DamageCause.SUICIDE && cause != DamageCause.FLY_INTO_WALL && cause != DamageCause.POISON)
|
cause != DamageCause.SUICIDE && cause != DamageCause.FLY_INTO_WALL && cause != DamageCause.POISON)
|
||||||
{
|
{
|
||||||
int durability = p.getInventory().getChestplate().getDurability();
|
int durability = p.getInventory().getChestplate().getDurability();
|
||||||
int maxDurability = p.getInventory().getChestplate().getType().getMaxDurability();
|
int maxDurability = p.getInventory().getChestplate().getType().getMaxDurability();
|
||||||
int newDurability = durability + ((int) (e.getDamage() / 4) > 1 ? (int) (e.getDamage() / 4) : 1);
|
int newDurability = durability + ((int) (e.getDamage() / 4) > 1 ? (int) (e.getDamage() / 4) : 1);
|
||||||
|
|
||||||
// If the elytra has the durability enchantment, we calculate the durability loss ourselves.
|
// If the elytra has the durability enchantment, we calculate the durability
|
||||||
|
// loss ourselves.
|
||||||
if (p.getInventory().getChestplate().containsEnchantment(Enchantment.DURABILITY))
|
if (p.getInventory().getChestplate().containsEnchantment(Enchantment.DURABILITY))
|
||||||
{
|
{
|
||||||
// Get a random int between 0 and 100 to use in deciding if the durability enchantment will take effect.
|
// Get a random int between 0 and 100 to use in deciding if the durability
|
||||||
Random r = new Random();
|
// enchantment will take effect.
|
||||||
int randomInt = r.nextInt(101);
|
Random r = new Random();
|
||||||
int enchantLevel = p.getInventory().getChestplate().getEnchantmentLevel(Enchantment.DURABILITY);
|
int randomInt = r.nextInt(101);
|
||||||
|
int enchantLevel = p.getInventory().getChestplate().getEnchantmentLevel(Enchantment.DURABILITY);
|
||||||
int durabilityDelta = (100 / (enchantLevel + 1)) < randomInt ? 0 : 1;
|
int durabilityDelta = (100 / (enchantLevel + 1)) < randomInt ? 0 : 1;
|
||||||
// If the durability equals/exceeds maxDurability, it's broken (0 = full item durability).
|
// If the durability equals/exceeds maxDurability, it's broken (0 = full item
|
||||||
|
// durability).
|
||||||
if (durability >= maxDurability)
|
if (durability >= maxDurability)
|
||||||
unenquipChestPlayer(p);
|
moveChestplateToInventory.accept(p);
|
||||||
else
|
else
|
||||||
newDurability = durability + durabilityDelta;
|
newDurability = durability + durabilityDelta;
|
||||||
}
|
}
|
||||||
@ -517,28 +499,37 @@ public class EventHandlers implements Listener
|
|||||||
if (newDurability >= maxDurability)
|
if (newDurability >= maxDurability)
|
||||||
{
|
{
|
||||||
newDurability = maxDurability;
|
newDurability = maxDurability;
|
||||||
unenquipChestPlayer(p);
|
moveChestplateToInventory.accept(p);
|
||||||
}
|
}
|
||||||
elytra.setDurability((short) (newDurability));
|
elytra.setDurability((short) (newDurability));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the player is trying to equip a broken elytra (and prevent that).
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void playerEquipsArmor(InventoryClickEvent e)
|
public void onEquip(ArmorEquipEvent e)
|
||||||
{
|
{
|
||||||
if (!(e.getWhoClicked() instanceof Player))
|
if (!e.getType().equals(ArmorType.CHESTPLATE) ||
|
||||||
|
!e.getNewArmorPiece().getType().equals(Material.ELYTRA) ||
|
||||||
|
e.getNewArmorPiece() == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Player player = (Player) e.getWhoClicked();
|
ArmorTier armorTier = nbtEditor.getArmorTier(e.getNewArmorPiece());
|
||||||
new BukkitRunnable()
|
AllowedToWearEnum allowed = isAllowedToWear(e.getNewArmorPiece(), e.getPlayer(), armorTier);
|
||||||
|
switch(allowed)
|
||||||
{
|
{
|
||||||
@Override
|
case ALLOWED:
|
||||||
public void run()
|
break;
|
||||||
{
|
case BROKEN:
|
||||||
verifyArmorInChestSlot(player);
|
plugin.messagePlayer(e.getPlayer(), plugin.getMyMessages().getString("MESSAGES.RepairNeeded"));
|
||||||
}
|
e.setCancelled(true);
|
||||||
}.runTaskLater(plugin, 1);
|
break;
|
||||||
|
case NOPERMISSION:
|
||||||
|
plugin.usageDeniedMessage(e.getPlayer(), armorTier);
|
||||||
|
e.setCancelled(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -28,7 +28,6 @@ public class GetArmorValueNew implements GetArmorValue
|
|||||||
plugin.myLogger(Level.INFO, "Failed to obtain armor value from NBT!");
|
plugin.myLogger(Level.INFO, "Failed to obtain armor value from NBT!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ public class GetArmorValueOld implements GetArmorValue
|
|||||||
String stringAtPos = nbtString.substring(pos, pos + 1);
|
String stringAtPos = nbtString.substring(pos, pos + 1);
|
||||||
return Integer.parseInt(stringAtPos);
|
return Integer.parseInt(stringAtPos);
|
||||||
}
|
}
|
||||||
else
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ public class NBTEditor
|
|||||||
Object nmsStack = asNMSCopy.invoke(null, item);
|
Object nmsStack = asNMSCopy.invoke(null, item);
|
||||||
Object compound = ((boolean) hasTag.invoke(nmsStack) ? getTag.invoke(nmsStack) : NBTTagCompound.newInstance());
|
Object compound = ((boolean) hasTag.invoke(nmsStack) ? getTag.invoke(nmsStack) : NBTTagCompound.newInstance());
|
||||||
Object modifiers = NBTTagList.newInstance();
|
Object modifiers = NBTTagList.newInstance();
|
||||||
Object armor = NBTTagCompound.newInstance();
|
Object armor = NBTTagCompound.newInstance(); // I should be able to simply add custom tags here!
|
||||||
setTag.invoke (armor, "AttributeName", NBTTagStringCtor.newInstance("generic.armor"));
|
setTag.invoke (armor, "AttributeName", NBTTagStringCtor.newInstance("generic.armor"));
|
||||||
setTag.invoke (armor, "Name", NBTTagStringCtor.newInstance("generic.armor"));
|
setTag.invoke (armor, "Name", NBTTagStringCtor.newInstance("generic.armor"));
|
||||||
setTag.invoke (armor, "Amount", NBTTagIntCtor.newInstance(armorProtection));
|
setTag.invoke (armor, "Amount", NBTTagIntCtor.newInstance(armorProtection));
|
||||||
|
@ -30,6 +30,8 @@ public class ConfigLoader
|
|||||||
private boolean noFlightDurability;
|
private boolean noFlightDurability;
|
||||||
private List<String> allowedEnchantments;
|
private List<String> allowedEnchantments;
|
||||||
private boolean allowMultipleProtectionEnchantments;
|
private boolean allowMultipleProtectionEnchantments;
|
||||||
|
public boolean bypassWearPerm;
|
||||||
|
public boolean bypassCraftPerm;
|
||||||
|
|
||||||
private ArrayList<ConfigOption<?>> configOptionsList;
|
private ArrayList<ConfigOption<?>> configOptionsList;
|
||||||
private ArmoredElytra plugin;
|
private ArmoredElytra plugin;
|
||||||
@ -87,7 +89,7 @@ public class ConfigLoader
|
|||||||
"Setting this to true will disable this plugin and remove any armored elytras it can find.",
|
"Setting this to true will disable this plugin and remove any armored elytras it can find.",
|
||||||
"It will check player's inventories and their end chest upon login and any regular chest when it is opened.",
|
"It will check player's inventories and their end chest upon login and any regular chest when it is opened.",
|
||||||
"This means it will take a while for all armored elytras to be removed from your server, but it doesn't take up ",
|
"This means it will take a while for all armored elytras to be removed from your server, but it doesn't take up ",
|
||||||
"a lot of resources, so you can just leave it installed and ignore it.",
|
"a lot of resources, so you can just leave the plugin enabled and ignore it.",
|
||||||
"Please do not forget to MAKE A BACKUP before enabling this option!"
|
"Please do not forget to MAKE A BACKUP before enabling this option!"
|
||||||
};
|
};
|
||||||
String[] languageFileComment =
|
String[] languageFileComment =
|
||||||
@ -102,11 +104,16 @@ public class ConfigLoader
|
|||||||
"elytra that has the protection enchantment with an enchanted book that has the blast protection enchantment",
|
"elytra that has the protection enchantment with an enchanted book that has the blast protection enchantment",
|
||||||
"would result in removal of the protection enchantment and addition of the blast protection enchantment."
|
"would result in removal of the protection enchantment and addition of the blast protection enchantment."
|
||||||
};
|
};
|
||||||
|
String[] permissionsComment =
|
||||||
|
{
|
||||||
|
"Globally bypass permissions for wearing and/or crafting amored elytras. Useful if permissions are unavailable."
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Set default list of allowed enchantments.
|
// Set default list of allowed enchantments.
|
||||||
allowedEnchantments = new ArrayList<>(Arrays.asList("DURABILITY", "PROTECTION_FIRE", "PROTECTION_EXPLOSIONS",
|
allowedEnchantments = new ArrayList<>(Arrays.asList("DURABILITY", "PROTECTION_FIRE", "PROTECTION_EXPLOSIONS",
|
||||||
"PROTECTION_PROJECTILE", "PROTECTION_ENVIRONMENTAL", "THORNS",
|
"PROTECTION_PROJECTILE", "PROTECTION_ENVIRONMENTAL", "THORNS",
|
||||||
"BINDING_CURSE", "VANISHING_CURSE"));
|
"BINDING_CURSE", "VANISHING_CURSE", "MENDING"));
|
||||||
|
|
||||||
FileConfiguration config = plugin.getConfig();
|
FileConfiguration config = plugin.getConfig();
|
||||||
|
|
||||||
@ -123,6 +130,8 @@ public class ConfigLoader
|
|||||||
enableDebug = addNewConfigOption(config, "enableDebug", false, debugComment);
|
enableDebug = addNewConfigOption(config, "enableDebug", false, debugComment);
|
||||||
uninstallMode = addNewConfigOption(config, "uninstallMode", false, uninstallComment);
|
uninstallMode = addNewConfigOption(config, "uninstallMode", false, uninstallComment);
|
||||||
languageFile = addNewConfigOption(config, "languageFile", "en_US", languageFileComment);
|
languageFile = addNewConfigOption(config, "languageFile", "en_US", languageFileComment);
|
||||||
|
bypassWearPerm = addNewConfigOption(config, "bypassWearPermissions", true, permissionsComment);
|
||||||
|
bypassCraftPerm = addNewConfigOption(config, "bypassCraftPermissions", true, null);
|
||||||
|
|
||||||
writeConfig();
|
writeConfig();
|
||||||
}
|
}
|
||||||
@ -239,4 +248,14 @@ public class ConfigLoader
|
|||||||
{
|
{
|
||||||
return allowedEnchantments;
|
return allowedEnchantments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean bypassWearPerm()
|
||||||
|
{
|
||||||
|
return bypassWearPerm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean bypassCraftPerm()
|
||||||
|
{
|
||||||
|
return bypassCraftPerm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,11 @@ public class Messages
|
|||||||
|
|
||||||
// Load the default en_US from the resources.
|
// Load the default en_US from the resources.
|
||||||
plugin.saveResource("en_US.txt", true);
|
plugin.saveResource("en_US.txt", true);
|
||||||
defaultFile.setWritable(false);
|
if (!defaultFile.setWritable(false))
|
||||||
|
{
|
||||||
|
plugin.myLogger(Level.WARNING, "Could not set default language file to read-only!");
|
||||||
|
plugin.myLogger(Level.WARNING, "This is not a big problem. Just remember not to edit the file!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read locale file.
|
// Read locale file.
|
||||||
@ -58,7 +62,7 @@ public class Messages
|
|||||||
String[] parts = sCurrentLine.split("=", 2);
|
String[] parts = sCurrentLine.split("=", 2);
|
||||||
key = parts[0];
|
key = parts[0];
|
||||||
value = parts[1].replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
value = parts[1].replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
||||||
String[] newLineSplitter = value.split("\\\\n"); // Wut? Can I haz more backslash?
|
String[] newLineSplitter = value.split("\\\\n");
|
||||||
|
|
||||||
String values = newLineSplitter[0];
|
String values = newLineSplitter[0];
|
||||||
|
|
||||||
@ -83,22 +87,11 @@ public class Messages
|
|||||||
// Get a string from a key. Returns "null" if null.
|
// Get a string from a key. Returns "null" if null.
|
||||||
public String getString(String key)
|
public String getString(String key)
|
||||||
{
|
{
|
||||||
String value = null;
|
String value = messageMap.get(key);
|
||||||
value = messageMap.get(key);
|
if (value != null)
|
||||||
if (value == null)
|
return value;
|
||||||
{
|
|
||||||
value = "ArmoredElytra: Translation not found! Contact server admin!";
|
|
||||||
plugin.myLogger(Level.WARNING, "Failed to get translation for key " + key);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStringReverse(String value)
|
plugin.myLogger(Level.WARNING, "Failed to get the translation for key " + key);
|
||||||
{
|
return "Translation for key \"" + key + "\" not found! Contact server admin!";
|
||||||
return messageMap.entrySet().stream()
|
|
||||||
.filter(e -> e.getValue().equals(value))
|
|
||||||
.map(Map.Entry::getKey)
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,425 +0,0 @@
|
|||||||
package nl.pim16aap2.armoredElytra.util;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
|
||||||
import org.bukkit.plugin.ServicePriority;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
import org.json.simple.JSONArray;
|
|
||||||
import org.json.simple.JSONObject;
|
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.zip.GZIPOutputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bStats collects some data for plugin authors.
|
|
||||||
*
|
|
||||||
* Check out https://bStats.org/ to learn more about bStats!
|
|
||||||
*/
|
|
||||||
public class Metrics
|
|
||||||
{
|
|
||||||
|
|
||||||
static
|
|
||||||
{
|
|
||||||
// You can use the property to disable the check in your test environment
|
|
||||||
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false"))
|
|
||||||
{
|
|
||||||
// Maven's Relocate is clever and changes strings, too. So we have to use this
|
|
||||||
// little "trick" ... :D
|
|
||||||
final String defaultPackage = new String(new byte[] { 'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't' });
|
|
||||||
final String examplePackage = new String(new byte[] { 'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e' });
|
|
||||||
// We want to make sure nobody just copy & pastes the example and use the wrong
|
|
||||||
// package names
|
|
||||||
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage))
|
|
||||||
{
|
|
||||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The version of this bStats class
|
|
||||||
public static final int B_STATS_VERSION = 1;
|
|
||||||
|
|
||||||
// The url to which the data is sent
|
|
||||||
private static final String URL = "https://bStats.org/submitData/bukkit";
|
|
||||||
|
|
||||||
// Should failed requests be logged?
|
|
||||||
private static boolean logFailedRequests;
|
|
||||||
|
|
||||||
// The uuid of the server
|
|
||||||
private static String serverUUID;
|
|
||||||
|
|
||||||
// The plugin
|
|
||||||
private final JavaPlugin plugin;
|
|
||||||
|
|
||||||
// A list with all custom charts
|
|
||||||
private final List<CustomChart> charts = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class constructor.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin which stats should be submitted.
|
|
||||||
*/
|
|
||||||
public Metrics(JavaPlugin plugin)
|
|
||||||
{
|
|
||||||
if (plugin == null)
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("Plugin cannot be null!");
|
|
||||||
}
|
|
||||||
this.plugin = plugin;
|
|
||||||
|
|
||||||
// Get the config file
|
|
||||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
|
||||||
File configFile = new File(bStatsFolder, "config.yml");
|
|
||||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
|
||||||
|
|
||||||
// Check if the config file exists
|
|
||||||
if (!config.isSet("serverUuid"))
|
|
||||||
{
|
|
||||||
|
|
||||||
// Add default values
|
|
||||||
config.addDefault("enabled", true);
|
|
||||||
// Every server gets it's unique random id.
|
|
||||||
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
|
||||||
// Should failed request be logged?
|
|
||||||
config.addDefault("logFailedRequests", false);
|
|
||||||
|
|
||||||
// Inform the server owners about bStats
|
|
||||||
config.options().header("bStats collects some data for plugin authors like how many servers are using their plugins.\n" + "To honor their work, you should not disable it.\n" + "This has nearly no effect on the server performance!\n" + "Check out https://bStats.org/ to learn more :)").copyDefaults(true);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
config.save(configFile);
|
|
||||||
}
|
|
||||||
catch (IOException ignored)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the data
|
|
||||||
serverUUID = config.getString("serverUuid");
|
|
||||||
logFailedRequests = config.getBoolean("logFailedRequests", false);
|
|
||||||
boolean found = false;
|
|
||||||
// Search for all other bStats Metrics classes to see if we are the first one
|
|
||||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
|
||||||
found = true; // We aren't the first
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catch (NoSuchFieldException ignored)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Register our service
|
|
||||||
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
// We are the first!
|
|
||||||
startSubmitting();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the Scheduler which submits our data every 30 minutes.
|
|
||||||
*/
|
|
||||||
private void startSubmitting()
|
|
||||||
{
|
|
||||||
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
|
|
||||||
timer.scheduleAtFixedRate(new TimerTask()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
if (!plugin.isEnabled())
|
|
||||||
{ // Plugin was disabled
|
|
||||||
timer.cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Nevertheless we want our code to run in the Bukkit main thread, so we have to
|
|
||||||
// use the Bukkit scheduler
|
|
||||||
// Don't be afraid! The connection to the bStats server is still async, only the
|
|
||||||
// stats collection is sync ;)
|
|
||||||
Bukkit.getScheduler().runTask(plugin, new Runnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
submitData();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, 1000 * 60 * 5, 1000 * 60 * 30);
|
|
||||||
// Submit the data every 30 minutes, first time after 5 minutes to give other
|
|
||||||
// plugins enough time to start
|
|
||||||
// WARNING: Changing the frequency has no effect but your plugin WILL be
|
|
||||||
// blocked/deleted!
|
|
||||||
// WARNING: Just don't do it!
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the plugin specific data. This method is called using Reflection.
|
|
||||||
*
|
|
||||||
* @return The plugin specific data.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public JSONObject getPluginData()
|
|
||||||
{
|
|
||||||
JSONObject data = new JSONObject();
|
|
||||||
|
|
||||||
String pluginName = plugin.getDescription().getName();
|
|
||||||
String pluginVersion = plugin.getDescription().getVersion();
|
|
||||||
|
|
||||||
data.put("pluginName", pluginName); // Append the name of the plugin
|
|
||||||
data.put("pluginVersion", pluginVersion); // Append the version of the plugin
|
|
||||||
JSONArray customCharts = new JSONArray();
|
|
||||||
for (CustomChart customChart : charts)
|
|
||||||
{
|
|
||||||
// Add the data of the custom charts
|
|
||||||
JSONObject chart = customChart.getRequestJsonObject();
|
|
||||||
if (chart == null)
|
|
||||||
{ // If the chart is null, we skip it
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
customCharts.add(chart);
|
|
||||||
}
|
|
||||||
data.put("customCharts", customCharts);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the server specific data.
|
|
||||||
*
|
|
||||||
* @return The server specific data.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private JSONObject getServerData()
|
|
||||||
{
|
|
||||||
// Minecraft specific data
|
|
||||||
int playerAmount;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Around MC 1.8 the return type was changed to a collection from an array,
|
|
||||||
// This fixes java.lang.NoSuchMethodError:
|
|
||||||
// org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
|
|
||||||
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
|
|
||||||
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class) ? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size() : ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
|
|
||||||
}
|
|
||||||
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
|
|
||||||
String bukkitVersion = org.bukkit.Bukkit.getVersion();
|
|
||||||
bukkitVersion = bukkitVersion.substring(bukkitVersion.indexOf("MC: ") + 4, bukkitVersion.length() - 1);
|
|
||||||
|
|
||||||
// OS/Java specific data
|
|
||||||
String javaVersion = System.getProperty("java.version");
|
|
||||||
String osName = System.getProperty("os.name");
|
|
||||||
String osArch = System.getProperty("os.arch");
|
|
||||||
String osVersion = System.getProperty("os.version");
|
|
||||||
int coreCount = Runtime.getRuntime().availableProcessors();
|
|
||||||
|
|
||||||
JSONObject data = new JSONObject();
|
|
||||||
|
|
||||||
data.put("serverUUID", serverUUID);
|
|
||||||
|
|
||||||
data.put("playerAmount", playerAmount);
|
|
||||||
data.put("onlineMode", onlineMode);
|
|
||||||
data.put("bukkitVersion", bukkitVersion);
|
|
||||||
|
|
||||||
data.put("javaVersion", javaVersion);
|
|
||||||
data.put("osName", osName);
|
|
||||||
data.put("osArch", osArch);
|
|
||||||
data.put("osVersion", osVersion);
|
|
||||||
data.put("coreCount", coreCount);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collects the data and sends it afterwards.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private void submitData()
|
|
||||||
{
|
|
||||||
final JSONObject data = getServerData();
|
|
||||||
|
|
||||||
JSONArray pluginData = new JSONArray();
|
|
||||||
// Search for all other bStats Metrics classes to get their plugin data
|
|
||||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
|
||||||
|
|
||||||
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
|
|
||||||
}
|
|
||||||
catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (NoSuchFieldException ignored)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data.put("plugins", pluginData);
|
|
||||||
|
|
||||||
// Create a new thread for the connection to the bStats server
|
|
||||||
new Thread(new Runnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Send the data
|
|
||||||
sendData(data);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
// Something went wrong! :(
|
|
||||||
if (logFailedRequests)
|
|
||||||
{
|
|
||||||
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends the data to the bStats server.
|
|
||||||
*
|
|
||||||
* @param data The data to send.
|
|
||||||
* @throws Exception If the request failed.
|
|
||||||
*/
|
|
||||||
private static void sendData(JSONObject data) throws Exception
|
|
||||||
{
|
|
||||||
if (data == null)
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("Data cannot be null!");
|
|
||||||
}
|
|
||||||
if (Bukkit.isPrimaryThread())
|
|
||||||
{
|
|
||||||
throw new IllegalAccessException("This method must not be called from the main thread!");
|
|
||||||
}
|
|
||||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
|
|
||||||
|
|
||||||
// Compress the data to save bandwidth
|
|
||||||
byte[] compressedData = compress(data.toString());
|
|
||||||
|
|
||||||
// Add headers
|
|
||||||
connection.setRequestMethod("POST");
|
|
||||||
connection.addRequestProperty("Accept", "application/json");
|
|
||||||
connection.addRequestProperty("Connection", "close");
|
|
||||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
|
||||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
|
||||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
|
||||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
|
||||||
|
|
||||||
// Send data
|
|
||||||
connection.setDoOutput(true);
|
|
||||||
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
|
||||||
outputStream.write(compressedData);
|
|
||||||
outputStream.flush();
|
|
||||||
outputStream.close();
|
|
||||||
|
|
||||||
connection.getInputStream().close(); // We don't care about the response - Just send our data :)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gzips the given String.
|
|
||||||
*
|
|
||||||
* @param str The string to gzip.
|
|
||||||
* @return The gzipped String.
|
|
||||||
* @throws IOException If the compression failed.
|
|
||||||
*/
|
|
||||||
private static byte[] compress(final String str) throws IOException
|
|
||||||
{
|
|
||||||
if (str == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
||||||
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
|
||||||
gzip.write(str.getBytes("UTF-8"));
|
|
||||||
gzip.close();
|
|
||||||
return outputStream.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a custom chart.
|
|
||||||
*/
|
|
||||||
public static abstract class CustomChart
|
|
||||||
{
|
|
||||||
|
|
||||||
// The id of the chart
|
|
||||||
final String chartId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class constructor.
|
|
||||||
*
|
|
||||||
* @param chartId The id of the chart.
|
|
||||||
*/
|
|
||||||
CustomChart(String chartId)
|
|
||||||
{
|
|
||||||
if (chartId == null || chartId.isEmpty())
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("ChartId cannot be null or empty!");
|
|
||||||
}
|
|
||||||
this.chartId = chartId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private JSONObject getRequestJsonObject()
|
|
||||||
{
|
|
||||||
JSONObject chart = new JSONObject();
|
|
||||||
chart.put("chartId", chartId);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
JSONObject data = getChartData();
|
|
||||||
if (data == null)
|
|
||||||
{
|
|
||||||
// If the data is null we don't send the chart.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
chart.put("data", data);
|
|
||||||
}
|
|
||||||
catch (Throwable t)
|
|
||||||
{
|
|
||||||
if (logFailedRequests)
|
|
||||||
{
|
|
||||||
Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return chart;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract JSONObject getChartData() throws Exception;
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,7 +6,6 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
public class Util
|
public class Util
|
||||||
@ -92,14 +91,4 @@ public class Util
|
|||||||
ret += 16;
|
ret += 16;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean playerHasCraftPerm(Player player, ArmorTier armorTier)
|
|
||||||
{
|
|
||||||
return player.hasPermission("armoredelytra.craft." + ArmorTier.getName(armorTier));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean playerHasWearPerm(Player player, ArmorTier armorTier)
|
|
||||||
{
|
|
||||||
return player.hasPermission("armoredelytra.wear." + ArmorTier.getName(armorTier));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
name: ArmoredElytra
|
name: ArmoredElytra
|
||||||
main: nl.pim16aap2.armoredElytra.ArmoredElytra
|
main: nl.pim16aap2.armoredElytra.ArmoredElytra
|
||||||
version: 2.4.8
|
version: ${project.version}
|
||||||
author: pim16aap2
|
author: pim16aap2
|
||||||
commands:
|
commands:
|
||||||
ArmoredElytra:
|
ArmoredElytra:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user