mirror of
https://github.com/songoda/EpicEnchants.git
synced 2024-11-15 23:26:01 +01:00
Added support for the SongodaCore NBT system.
This commit is contained in:
parent
c452be47f4
commit
eda68bc4be
@ -19,7 +19,6 @@ import com.songoda.epicenchants.listeners.item.WhiteScrollListener;
|
||||
import com.songoda.epicenchants.managers.*;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import com.songoda.epicenchants.utils.EnchantUtils;
|
||||
import com.songoda.epicenchants.utils.Metrics;
|
||||
import com.songoda.epicenchants.utils.SpecialItems;
|
||||
import com.songoda.epicenchants.utils.objects.FastInv;
|
||||
import com.songoda.epicenchants.utils.settings.Settings;
|
||||
@ -111,9 +110,6 @@ public class EpicEnchants extends SongodaPlugin {
|
||||
pluginManager.registerEvents(new BlackScrollListener(this), this);
|
||||
pluginManager.registerEvents(new DustListener(this), this);
|
||||
|
||||
// Start Metrics
|
||||
new Metrics(this);
|
||||
|
||||
if (!enchantManager.getValues().isEmpty()) {
|
||||
getLogger().info("Successfully loaded enchants: " + enchantManager.getValues().stream().map(Enchant::getIdentifier).collect(Collectors.joining(", ")));
|
||||
}
|
||||
@ -125,6 +121,11 @@ public class EpicEnchants extends SongodaPlugin {
|
||||
fileManager.loadFiles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataLoad() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginDisable() {
|
||||
}
|
||||
@ -152,10 +153,6 @@ public class EpicEnchants extends SongodaPlugin {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataLoad() {
|
||||
}
|
||||
|
||||
public EnchantManager getEnchantManager() {
|
||||
return this.enchantManager;
|
||||
}
|
||||
|
@ -1,13 +1,20 @@
|
||||
package com.songoda.epicenchants.effect.effects;
|
||||
|
||||
import com.songoda.core.nms.NmsManager;
|
||||
import com.songoda.epicenchants.effect.EffectExecutor;
|
||||
import com.songoda.epicenchants.enums.EventType;
|
||||
import com.songoda.epicenchants.objects.LeveledModifier;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.*;
|
||||
import com.songoda.core.nms.nbt.NBTEntity;
|
||||
import com.songoda.epicenchants.utils.objects.ItemBuilder;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeInstance;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Monster;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -85,22 +92,12 @@ public class SpawnMob extends EffectExecutor {
|
||||
((Monster) entity).setTarget(opponent);
|
||||
}
|
||||
|
||||
NBTEntity nbtEntity = new NBTEntity(entity);
|
||||
if (entity instanceof LivingEntity) {
|
||||
AttributeInstance attack = ((LivingEntity) entity).getAttribute(Attribute.GENERIC_ATTACK_DAMAGE);
|
||||
attack.setBaseValue(attackDamage.get(level, (int) Math.round(attack.getBaseValue()), user, opponent));
|
||||
|
||||
nbtEntity.setBoolean(user.getUniqueId().toString(), true);
|
||||
|
||||
NBTCompoundList list = nbtEntity.getCompoundList("Attributes");
|
||||
|
||||
for (int j = 0; j < list.size(); j++) {
|
||||
NBTListCompound lc = list.get(j);
|
||||
if (lc.getString("Name").equals("generic.attackDamage")) {
|
||||
lc.setDouble("Base", attackDamage.get(level, (int) Math.round(lc.getDouble("Base")), user, opponent));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lc.getString("Name").equals("generic.maxHealth")) {
|
||||
lc.setDouble("Base", health.get(level, (int) Math.round(lc.getDouble("Base")), user, opponent));
|
||||
}
|
||||
AttributeInstance heal = ((LivingEntity) entity).getAttribute(Attribute.GENERIC_MAX_HEALTH);
|
||||
heal.setBaseValue(health.get(level, (int) Math.round(heal.getBaseValue()), user, opponent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.songoda.epicenchants.listeners;
|
||||
|
||||
import com.songoda.core.nms.NmsManager;
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.enums.TriggerType;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTEntity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Monster;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -10,7 +10,11 @@ import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.*;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
|
||||
import static com.songoda.epicenchants.enums.TriggerType.*;
|
||||
@ -118,11 +122,10 @@ public class EntityListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onEntityTargetLivingEntity(EntityTargetLivingEntityEvent event) {
|
||||
if (event.getEntity() == null || event.getTarget() == null) {
|
||||
if (event.getTarget() == null)
|
||||
return;
|
||||
}
|
||||
|
||||
if (new NBTEntity(event.getEntity()).hasKey(event.getTarget().getUniqueId().toString())) {
|
||||
if (NmsManager.getNbt().of(event.getEntity()).has(event.getTarget().getUniqueId().toString())) {
|
||||
//TODO: Add team support.
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package com.songoda.epicenchants.listeners.item;
|
||||
|
||||
import com.songoda.core.nms.nbt.NBTCompound;
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTCompound;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.single.RomanNumber;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -17,7 +17,7 @@ public class BlackScrollListener extends ItemListener {
|
||||
|
||||
@Override
|
||||
void onApply(InventoryClickEvent event, NBTItem cursor, NBTItem current) {
|
||||
if (!cursor.hasKey("black-scroll") || !cursor.getBoolean("black-scroll")) {
|
||||
if (!cursor.has("black-scroll") || !cursor.getNBTObject("black-scroll").asBoolean()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -31,11 +31,11 @@ public class BlackScrollListener extends ItemListener {
|
||||
}
|
||||
|
||||
String id = getRandomElement(compound.getKeys());
|
||||
int level = compound.getInteger(id);
|
||||
int level = compound.getInt(id);
|
||||
Enchant enchant = instance.getEnchantManager().getValueUnsafe(id);
|
||||
ItemStack toSet = instance.getEnchantUtils().removeEnchant(event.getCurrentItem(), enchant);
|
||||
|
||||
event.getWhoClicked().getInventory().addItem(enchant.getBook().get(enchant, level, cursor.getInteger("success-rate"), 100));
|
||||
event.getWhoClicked().getInventory().addItem(enchant.getBook().get(enchant, level, cursor.getInt("success-rate"), 100));
|
||||
event.setCurrentItem(toSet);
|
||||
|
||||
instance.getLocale().getMessage("blackscroll.success")
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.songoda.epicenchants.listeners.item;
|
||||
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.enums.EnchantResult;
|
||||
@ -7,7 +8,6 @@ import com.songoda.epicenchants.events.EnchantApplyEvent;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import com.songoda.epicenchants.objects.Group;
|
||||
import com.songoda.epicenchants.utils.Tuple;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.single.GeneralUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -17,7 +17,10 @@ import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.songoda.epicenchants.enums.EnchantResult.*;
|
||||
import static com.songoda.epicenchants.enums.EnchantResult.ALREADY_APPLIED;
|
||||
import static com.songoda.epicenchants.enums.EnchantResult.BROKEN_FAILURE;
|
||||
import static com.songoda.epicenchants.enums.EnchantResult.CONFLICT;
|
||||
import static com.songoda.epicenchants.enums.EnchantResult.MAXED_OUT;
|
||||
import static java.util.concurrent.ThreadLocalRandom.current;
|
||||
|
||||
public class BookListener extends ItemListener {
|
||||
@ -27,31 +30,31 @@ public class BookListener extends ItemListener {
|
||||
|
||||
@Override
|
||||
void onApply(InventoryClickEvent event, NBTItem cursor, NBTItem current) {
|
||||
if (!cursor.hasKey("book-item") || !cursor.getBoolean("book-item")) {
|
||||
if (!cursor.has("book-item") || !cursor.getNBTObject("book-item").asBoolean()) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
ItemStack toApply = event.getCurrentItem();
|
||||
Enchant enchant = instance.getEnchantManager().getValue(cursor.getString("enchant")).orElseThrow(() -> new IllegalStateException("Book without enchant!"));
|
||||
Enchant enchant = instance.getEnchantManager().getValue(cursor.getNBTObject("enchant").asString()).orElseThrow(() -> new IllegalStateException("Book without enchant!"));
|
||||
|
||||
if (!enchant.getItemWhitelist().contains(CompatibleMaterial.getMaterial(current.getItem()))) {
|
||||
if (!enchant.getItemWhitelist().contains(CompatibleMaterial.getMaterial(current.finish()))) {
|
||||
return;
|
||||
}
|
||||
// get total amount of enchantments on item
|
||||
int currentEnchantmentTotal = instance.getEnchantUtils().getEnchants(toApply).size();
|
||||
//int maxAllowedApply = instance.getEnchantUtils().getMaximumEnchantsCanApply((Player) event.getWhoClicked());
|
||||
int maxAllowedApply = instance.getEnchantUtils().getMaximumEnchantsCanApplyItem(toApply,(Player) event.getWhoClicked());
|
||||
int maxAllowedApply = instance.getEnchantUtils().getMaximumEnchantsCanApplyItem(toApply, (Player) event.getWhoClicked());
|
||||
// item is at max enchantments
|
||||
if (currentEnchantmentTotal >= maxAllowedApply) {
|
||||
instance.getLocale().getMessage("enchants.maxallowed").processPlaceholder("max_enchants", maxAllowedApply).sendPrefixedMessage(event.getWhoClicked());
|
||||
return;
|
||||
}
|
||||
|
||||
int level = cursor.getInteger("level");
|
||||
int successRate = cursor.getInteger("success-rate");
|
||||
int destroyRate = cursor.getInteger("destroy-rate");
|
||||
int level = cursor.getNBTObject("level").asInt();
|
||||
int successRate = cursor.getNBTObject("success-rate").asInt();
|
||||
int destroyRate = cursor.getNBTObject("destroy-rate").asInt();
|
||||
|
||||
EnchantApplyEvent enchantEvent = new EnchantApplyEvent(toApply, enchant, level, successRate, destroyRate);
|
||||
Bukkit.getPluginManager().callEvent(enchantEvent);
|
||||
@ -79,7 +82,7 @@ public class BookListener extends ItemListener {
|
||||
|
||||
@Override
|
||||
void onClick(PlayerInteractEvent event, NBTItem clicked) {
|
||||
if (!clicked.hasKey("mystery-book") || !clicked.getBoolean("mystery-book")) {
|
||||
if (!clicked.has("mystery-book") || !clicked.getNBTObject("mystery-book").asBoolean()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -89,7 +92,7 @@ public class BookListener extends ItemListener {
|
||||
return;
|
||||
}
|
||||
|
||||
Group group = instance.getGroupManager().getValue(clicked.getString("group")).orElseThrow(() -> new IllegalStateException("Book without group!"));
|
||||
Group group = instance.getGroupManager().getValue(clicked.getNBTObject("group").asString()).orElseThrow(() -> new IllegalStateException("Book without group!"));
|
||||
|
||||
Optional<Enchant> enchant = instance.getEnchantManager().getRandomEnchant(group);
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
package com.songoda.epicenchants.listeners.item;
|
||||
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import com.songoda.epicenchants.objects.Group;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
@ -16,28 +16,28 @@ public class DustListener extends ItemListener {
|
||||
|
||||
@Override
|
||||
void onApply(InventoryClickEvent event, NBTItem cursor, NBTItem current) {
|
||||
if (!cursor.hasKey("dust") || !cursor.getBoolean("dust")) {
|
||||
if (!cursor.has("dust") || !cursor.getNBTObject("dust").asBoolean()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!current.hasKey("book-item") || !current.getBoolean("book-item")) {
|
||||
if (!current.has("book-item") || !current.getNBTObject("book-item").asBoolean()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Enchant enchant = instance.getEnchantManager().getValue(current.getString("enchant")).orElseThrow(() -> new IllegalStateException("Book without enchant!"));
|
||||
Enchant enchant = instance.getEnchantManager().getValue(current.getNBTObject("enchant").asString()).orElseThrow(() -> new IllegalStateException("Book without enchant!"));
|
||||
|
||||
if (!enchant.getGroup().equals(instance.getGroupManager().getValue(cursor.getString("group")).orElseThrow(() -> new IllegalStateException("Dust without group!")))) {
|
||||
if (!enchant.getGroup().equals(instance.getGroupManager().getValue(cursor.getNBTObject("group").asString()).orElseThrow(() -> new IllegalStateException("Dust without group!")))) {
|
||||
return;
|
||||
}
|
||||
|
||||
int successRate = current.getInteger("success-rate");
|
||||
int successRate = current.getNBTObject("success-rate").asInt();
|
||||
|
||||
if (successRate == 100) {
|
||||
return;
|
||||
}
|
||||
|
||||
successRate = successRate + cursor.getInteger("percentage") > 100 ? 100 : successRate + cursor.getInteger("percentage");
|
||||
event.setCurrentItem(enchant.getBook().get(enchant, current.getInteger("level"), successRate, current.getInteger("destroy-rate")));
|
||||
successRate = Math.min(successRate + cursor.getNBTObject("percentage").asInt(), 100);
|
||||
event.setCurrentItem(enchant.getBook().get(enchant, current.getNBTObject("level").asInt(), successRate, current.getNBTObject("destroy-rate").asInt()));
|
||||
|
||||
event.setCancelled(true);
|
||||
useItem(event);
|
||||
@ -45,7 +45,7 @@ public class DustListener extends ItemListener {
|
||||
|
||||
@Override
|
||||
void onClick(PlayerInteractEvent event, NBTItem clicked) {
|
||||
if (!clicked.hasKey("secret-dust") || !clicked.getBoolean("secret-dust")) {
|
||||
if (!clicked.has("secret-dust") || !clicked.getNBTObject("secret-dust").asBoolean()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -55,8 +55,8 @@ public class DustListener extends ItemListener {
|
||||
return;
|
||||
}
|
||||
|
||||
Group group = instance.getGroupManager().getValueUnsafe(clicked.getString("group"));
|
||||
int rate = ThreadLocalRandom.current().nextInt(clicked.getInteger("min-rate"), clicked.getInteger("max-rate"));
|
||||
Group group = instance.getGroupManager().getValueUnsafe(clicked.getNBTObject("group").asString());
|
||||
int rate = ThreadLocalRandom.current().nextInt(clicked.getNBTObject("min-rate").asInt(), clicked.getNBTObject("max-rate").asInt());
|
||||
|
||||
useItem(event);
|
||||
event.getPlayer().getInventory().addItem(instance.getSpecialItems().getDust(group, null, rate, false));
|
||||
|
@ -1,7 +1,8 @@
|
||||
package com.songoda.epicenchants.listeners.item;
|
||||
|
||||
import com.songoda.core.nms.NmsManager;
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@ -31,7 +32,7 @@ public abstract class ItemListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
onApply(event, new NBTItem(event.getCursor()), new NBTItem(event.getCurrentItem()));
|
||||
onApply(event, NmsManager.getNbt().of(event.getCursor()), NmsManager.getNbt().of(event.getCurrentItem()));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
@ -44,7 +45,7 @@ public abstract class ItemListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
onClick(event, new NBTItem(event.getItem()));
|
||||
onClick(event, NmsManager.getNbt().of(event.getItem()));
|
||||
}
|
||||
|
||||
void useItem(InventoryClickEvent event) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.songoda.epicenchants.listeners.item;
|
||||
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.objects.ItemBuilder;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -14,22 +14,22 @@ public class WhiteScrollListener extends ItemListener {
|
||||
|
||||
@Override
|
||||
void onApply(InventoryClickEvent event, NBTItem cursor, NBTItem current) {
|
||||
if (!cursor.hasKey("white-scroll") || !cursor.getBoolean("white-scroll")) {
|
||||
if (!cursor.has("white-scroll") || !cursor.getNBTObject("white-scroll").asBoolean()) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
if (current.hasKey("protected")) {
|
||||
if (current.has("protected")) {
|
||||
instance.getLocale().getMessage("whitescroll.alreadyapplied")
|
||||
.sendPrefixedMessage(event.getWhoClicked());
|
||||
return;
|
||||
}
|
||||
|
||||
current.setBoolean("protected", true);
|
||||
current.set("protected", true);
|
||||
instance.getLocale().getMessage("whitescrollapplied").sendPrefixedMessage(event.getWhoClicked());
|
||||
|
||||
ItemStack toSet = new ItemBuilder(current.getItem()).addLore(instance.getSpecialItems().getWhiteScrollLore()).build();
|
||||
ItemStack toSet = new ItemBuilder(current.finish()).addLore(instance.getSpecialItems().getWhiteScrollLore()).build();
|
||||
|
||||
event.getClickedInventory().setItem(event.getSlot(), toSet);
|
||||
useItem(event);
|
||||
|
@ -1,11 +1,12 @@
|
||||
package com.songoda.epicenchants.menus;
|
||||
|
||||
import com.songoda.core.hooks.EconomyManager;
|
||||
import com.songoda.core.nms.NmsManager;
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import com.songoda.epicenchants.objects.Group;
|
||||
import com.songoda.epicenchants.objects.Placeholder;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.objects.FastInv;
|
||||
import com.songoda.epicenchants.utils.objects.ItemBuilder;
|
||||
import com.songoda.epicenchants.utils.single.GeneralUtils;
|
||||
@ -19,8 +20,10 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.songoda.epicenchants.objects.Placeholder.of;
|
||||
import static com.songoda.epicenchants.utils.single.Experience.*;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.*;
|
||||
import static com.songoda.epicenchants.utils.single.Experience.changeExp;
|
||||
import static com.songoda.epicenchants.utils.single.Experience.getExp;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.color;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.getSlots;
|
||||
|
||||
public class AlchemistMenu extends FastInv {
|
||||
private final EpicEnchants instance;
|
||||
@ -120,9 +123,9 @@ public class AlchemistMenu extends FastInv {
|
||||
ItemStack toHandle = itemStack.clone();
|
||||
toHandle.setAmount(1);
|
||||
|
||||
NBTItem nbtItem = new NBTItem(toHandle);
|
||||
NBTItem nbtItem = NmsManager.getNbt().of(toHandle);
|
||||
|
||||
if (!nbtItem.hasKey("book-item") && !nbtItem.hasKey("dust")) {
|
||||
if (!nbtItem.has("book-item") && !nbtItem.has("dust")) {
|
||||
instance.getLocale().getMessage("alchemist.notinterested").sendPrefixedMessage(player);
|
||||
return false;
|
||||
}
|
||||
@ -133,13 +136,13 @@ public class AlchemistMenu extends FastInv {
|
||||
return false;
|
||||
}
|
||||
|
||||
int successRate = nbtItem.getInteger("success-rate");
|
||||
int successRate = nbtItem.getNBTObject("success-rate").asInt();
|
||||
|
||||
// Both slots empty
|
||||
if (getInventory().getItem(LEFT_SLOT) == null && getInventory().getItem(RIGHT_SLOT) == null) {
|
||||
if (nbtItem.hasKey("book-item")) {
|
||||
Enchant enchant = instance.getEnchantManager().getValue(nbtItem.getString("enchant")).orElseThrow(() -> new IllegalStateException("Book without enchant!"));
|
||||
int level = nbtItem.getInteger("level");
|
||||
if (nbtItem.has("book-item")) {
|
||||
Enchant enchant = instance.getEnchantManager().getValue(nbtItem.getNBTObject("enchant").asString()).orElseThrow(() -> new IllegalStateException("Book without enchant!"));
|
||||
int level = nbtItem.getNBTObject("level").asInt();
|
||||
|
||||
if (enchant.getMaxLevel() == level) {
|
||||
instance.getLocale().getMessage("alchemist.maxlevelbook")
|
||||
@ -147,7 +150,7 @@ public class AlchemistMenu extends FastInv {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
Group group = instance.getGroupManager().getValue(nbtItem.getString("group")).orElseThrow(() -> new IllegalStateException("Dust without group!"));
|
||||
Group group = instance.getGroupManager().getValue(nbtItem.getNBTObject("group").asString()).orElseThrow(() -> new IllegalStateException("Dust without group!"));
|
||||
|
||||
if (group.getOrder() == instance.getGroupManager().getValues().stream().mapToInt(Group::getOrder).max().orElse(0) || successRate == 100) {
|
||||
instance.getLocale().getMessage("alchemist." + (successRate == 100 ? "maxpercentagedust" : "highestgroupdust"))
|
||||
@ -160,21 +163,21 @@ public class AlchemistMenu extends FastInv {
|
||||
return true;
|
||||
}
|
||||
|
||||
NBTItem other = new NBTItem(getInventory().getItem(getInventory().getItem(LEFT_SLOT) == null ? RIGHT_SLOT : LEFT_SLOT));
|
||||
NBTItem other = NmsManager.getNbt().of(getInventory().getItem(getInventory().getItem(LEFT_SLOT) == null ? RIGHT_SLOT : LEFT_SLOT));
|
||||
int emptySlot = getInventory().getItem(LEFT_SLOT) == null ? LEFT_SLOT : RIGHT_SLOT;
|
||||
|
||||
if (other.hasKey("book-item")) {
|
||||
if (!nbtItem.getString("enchant").equals(other.getString("enchant"))) {
|
||||
if (other.has("book-item")) {
|
||||
if (!nbtItem.getNBTObject("enchant").asString().equals(other.getNBTObject("enchant").asString())) {
|
||||
instance.getLocale().getMessage("alchemist.differentenchantment").sendPrefixedMessage(player);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!nbtItem.getInteger("level").equals(other.getInteger("level"))) {
|
||||
if (nbtItem.getNBTObject("level").asInt() != other.getNBTObject("level").asInt()) {
|
||||
instance.getLocale().getMessage("alchemist.differentlevels").sendPrefixedMessage(player);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!nbtItem.getString("group").equals(other.getString("group"))) {
|
||||
if (!nbtItem.getNBTObject("group").asString().equals(other.getNBTObject("group").asString())) {
|
||||
instance.getLocale().getMessage("alchemist.differentgroups").sendPrefixedMessage(player);
|
||||
return false;
|
||||
}
|
||||
@ -197,18 +200,18 @@ public class AlchemistMenu extends FastInv {
|
||||
return;
|
||||
}
|
||||
|
||||
NBTItem leftItem = new NBTItem(getInventory().getItem(LEFT_SLOT));
|
||||
NBTItem rightItem = new NBTItem(getInventory().getItem(RIGHT_SLOT));
|
||||
NBTItem leftItem = NmsManager.getNbt().of(getInventory().getItem(LEFT_SLOT));
|
||||
NBTItem rightItem = NmsManager.getNbt().of(getInventory().getItem(RIGHT_SLOT));
|
||||
int ecoCost;
|
||||
int expCost;
|
||||
|
||||
if (leftItem.hasKey("book-item")) {
|
||||
int level = leftItem.getInteger("level");
|
||||
Enchant enchant = instance.getEnchantManager().getValue(leftItem.getString("enchant")).orElseThrow(() -> new IllegalStateException("Book without enchant!"));
|
||||
int leftSuccess = leftItem.getInteger("success-rate");
|
||||
int rightSuccess = rightItem.getInteger("success-rate");
|
||||
int leftDestroy = leftItem.getInteger("destroy-rate");
|
||||
int rightDestroy = rightItem.getInteger("destroy-rate");
|
||||
if (leftItem.has("book-item")) {
|
||||
int level = leftItem.getNBTObject("level").asInt();
|
||||
Enchant enchant = instance.getEnchantManager().getValue(leftItem.getNBTObject("enchant").asString()).orElseThrow(() -> new IllegalStateException("Book without enchant!"));
|
||||
int leftSuccess = leftItem.getNBTObject("success-rate").asInt();
|
||||
int rightSuccess = rightItem.getNBTObject("success-rate").asInt();
|
||||
int leftDestroy = leftItem.getNBTObject("destroy-rate").asInt();
|
||||
int rightDestroy = rightItem.getNBTObject("destroy-rate").asInt();
|
||||
|
||||
Placeholder[] placeholders = new Placeholder[]{
|
||||
of("left_success_rate", leftSuccess),
|
||||
@ -235,11 +238,11 @@ public class AlchemistMenu extends FastInv {
|
||||
|
||||
getInventory().setItem(PREVIEW_SLOT, enchant.getBook().get(enchant, level + 1, successRate, destroyRate));
|
||||
} else {
|
||||
Group group = instance.getGroupManager().getValue(leftItem.getString("group")).orElseThrow(() -> new IllegalStateException("Dust without group!"));
|
||||
Group group = instance.getGroupManager().getValue(leftItem.getNBTObject("group").asString()).orElseThrow(() -> new IllegalStateException("Dust without group!"));
|
||||
|
||||
Placeholder[] placeholders = new Placeholder[]{
|
||||
of("left_percentage", leftItem.getInteger("percentage")),
|
||||
of("right_percentage", rightItem.getInteger("percentage"))
|
||||
of("left_percentage", leftItem.getNBTObject("percentage").asInt()),
|
||||
of("right_percentage", rightItem.getNBTObject("percentage").asInt())
|
||||
};
|
||||
|
||||
int successRate = getFromFormula("dust.percentage-formula", placeholders);
|
||||
|
@ -1,10 +1,11 @@
|
||||
package com.songoda.epicenchants.menus;
|
||||
|
||||
import com.songoda.core.nms.NmsManager;
|
||||
import com.songoda.core.nms.nbt.NBTCompound;
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.enums.ItemType;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTCompound;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.objects.FastInv;
|
||||
import com.songoda.epicenchants.utils.objects.ItemBuilder;
|
||||
import org.bukkit.Material;
|
||||
@ -22,8 +23,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.songoda.epicenchants.enums.ItemType.*;
|
||||
import static com.songoda.epicenchants.objects.Placeholder.of;
|
||||
import static com.songoda.epicenchants.enums.ItemType.BOOK;
|
||||
import static com.songoda.epicenchants.enums.ItemType.ENCHANTED;
|
||||
import static com.songoda.epicenchants.enums.ItemType.NONE;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.color;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.getSlots;
|
||||
import static java.util.Arrays.stream;
|
||||
@ -168,9 +170,9 @@ public class TinkererMenu extends FastInv {
|
||||
return NONE;
|
||||
}
|
||||
|
||||
NBTItem nbtItem = new NBTItem(itemStack);
|
||||
NBTItem nbtItem = NmsManager.getNbt().of(itemStack);
|
||||
|
||||
if (nbtItem.hasKey("book-item")) {
|
||||
if (nbtItem.has("book-item")) {
|
||||
return BOOK;
|
||||
}
|
||||
|
||||
@ -205,7 +207,7 @@ public class TinkererMenu extends FastInv {
|
||||
|
||||
switch (itemType) {
|
||||
case BOOK:
|
||||
getInventory().setItem(emptySlot.get().getValue(), instance.getSpecialItems().getSecretDust(new NBTItem(finalItemStack)));
|
||||
getInventory().setItem(emptySlot.get().getValue(), instance.getSpecialItems().getSecretDust(NmsManager.getNbt().of(finalItemStack)));
|
||||
break;
|
||||
case ENCHANTED:
|
||||
getInventory().setItem(emptySlot.get().getValue(), instance.getHookManager().getUltimateBottles().get().createBottle("Tinkerer", getExpAmount(finalItemStack)));
|
||||
@ -235,9 +237,9 @@ public class TinkererMenu extends FastInv {
|
||||
total.addAndGet(section.getInt(enchantment.getName(), section.getInt("DEFAULT")) * level);
|
||||
});
|
||||
|
||||
NBTItem nbtItem = new NBTItem(itemStack);
|
||||
NBTItem nbtItem = NmsManager.getNbt().of(itemStack);
|
||||
|
||||
if (!nbtItem.hasKey("enchants")) {
|
||||
if (!nbtItem.has("enchants")) {
|
||||
return total.get();
|
||||
}
|
||||
|
||||
@ -249,7 +251,7 @@ public class TinkererMenu extends FastInv {
|
||||
|
||||
enchantments.getKeys().forEach(key -> {
|
||||
Enchant enchant = instance.getEnchantManager().getValueUnsafe(key);
|
||||
total.addAndGet(section.getInt(enchant.getIdentifier(), enchant.getGroup().getTinkererExp()) * enchantments.getInteger(key));
|
||||
total.addAndGet(section.getInt(enchant.getIdentifier(), enchant.getGroup().getTinkererExp()) * enchantments.getInt(key));
|
||||
});
|
||||
|
||||
return total.get();
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.songoda.epicenchants.objects;
|
||||
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.objects.ItemBuilder;
|
||||
import com.songoda.epicenchants.utils.settings.Settings;
|
||||
import com.songoda.epicenchants.utils.single.GeneralUtils;
|
||||
@ -82,13 +82,13 @@ public class BookItem {
|
||||
.lore(toSet);
|
||||
|
||||
NBTItem nbtItem = itemBuilder.nbt();
|
||||
nbtItem.setBoolean("book-item", true);
|
||||
nbtItem.setInteger("success-rate", successRate);
|
||||
nbtItem.setInteger("destroy-rate", destroyRate);
|
||||
nbtItem.setInteger("level", level);
|
||||
nbtItem.setString("enchant", enchant.getIdentifier());
|
||||
nbtItem.set("book-item", true);
|
||||
nbtItem.set("success-rate", successRate);
|
||||
nbtItem.set("destroy-rate", destroyRate);
|
||||
nbtItem.set("level", level);
|
||||
nbtItem.set("enchant", enchant.getIdentifier());
|
||||
|
||||
return nbtItem.getItem();
|
||||
return nbtItem.finish();
|
||||
}
|
||||
|
||||
public static class BookItemBuilder {
|
||||
|
@ -1,13 +1,14 @@
|
||||
package com.songoda.epicenchants.utils;
|
||||
|
||||
import com.songoda.core.nms.NmsManager;
|
||||
import com.songoda.core.nms.nbt.NBTCompound;
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import com.songoda.core.utils.TextUtils;
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.enums.EnchantResult;
|
||||
import com.songoda.epicenchants.enums.EventType;
|
||||
import com.songoda.epicenchants.enums.TriggerType;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTCompound;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.objects.ItemBuilder;
|
||||
import com.songoda.epicenchants.utils.settings.Settings;
|
||||
import com.songoda.epicenchants.utils.single.GeneralUtils;
|
||||
@ -20,10 +21,23 @@ import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.songoda.epicenchants.enums.EnchantResult.*;
|
||||
import static com.songoda.epicenchants.enums.EnchantResult.ALREADY_APPLIED;
|
||||
import static com.songoda.epicenchants.enums.EnchantResult.BROKEN_FAILURE;
|
||||
import static com.songoda.epicenchants.enums.EnchantResult.CONFLICT;
|
||||
import static com.songoda.epicenchants.enums.EnchantResult.FAILURE;
|
||||
import static com.songoda.epicenchants.enums.EnchantResult.MAXED_OUT;
|
||||
import static com.songoda.epicenchants.enums.EnchantResult.PROTECTED;
|
||||
import static com.songoda.epicenchants.enums.EnchantResult.SUCCESS;
|
||||
import static com.songoda.epicenchants.enums.TriggerType.HELD_ITEM;
|
||||
|
||||
public class EnchantUtils {
|
||||
@ -35,7 +49,7 @@ public class EnchantUtils {
|
||||
}
|
||||
|
||||
public Tuple<ItemStack, EnchantResult> apply(ItemStack itemStack, Enchant enchant, int level, int successRate, int destroyRate) {
|
||||
boolean hasProtection = new NBTItem(itemStack).hasKey("protected");
|
||||
boolean hasProtection = NmsManager.getNbt().of(itemStack).has("protected");
|
||||
|
||||
Map<Enchant, Integer> currentEnchantMap = getEnchants(itemStack);
|
||||
Set<String> currentIds = currentEnchantMap.keySet().stream().map(Enchant::getIdentifier).collect(Collectors.toSet());
|
||||
@ -57,8 +71,8 @@ public class EnchantUtils {
|
||||
if (GeneralUtils.chance(destroyRate)) {
|
||||
if (hasProtection) {
|
||||
NBTItem nbtItem = new ItemBuilder(itemStack).removeLore(instance.getSpecialItems().getWhiteScrollLore()).nbt();
|
||||
nbtItem.removeKey("protected");
|
||||
return Tuple.of(nbtItem.getItem(), PROTECTED);
|
||||
nbtItem.remove("protected");
|
||||
return Tuple.of(nbtItem.finish(), PROTECTED);
|
||||
}
|
||||
return Tuple.of(new ItemStack(Material.AIR), BROKEN_FAILURE);
|
||||
}
|
||||
@ -80,22 +94,19 @@ public class EnchantUtils {
|
||||
|
||||
NBTItem nbtItem = itemBuilder.nbt();
|
||||
|
||||
nbtItem.addCompound("enchants");
|
||||
|
||||
NBTCompound compound = nbtItem.getCompound("enchants");
|
||||
compound.setInteger(enchant.getIdentifier(), level);
|
||||
compound.set(enchant.getIdentifier(), level);
|
||||
|
||||
return Tuple.of(nbtItem.getItem(), SUCCESS);
|
||||
return Tuple.of(nbtItem.finish(), SUCCESS);
|
||||
}
|
||||
|
||||
public Map<Enchant, Integer> getEnchants(ItemStack itemStack) {
|
||||
if (itemStack == null || itemStack.getType() == Material.AIR) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
NBTItem nbtItem = NmsManager.getNbt().of(itemStack);
|
||||
|
||||
NBTItem nbtItem = new NBTItem(itemStack);
|
||||
|
||||
if (!nbtItem.hasNBTData() || !nbtItem.hasKey("enchants")) {
|
||||
if (!nbtItem.has("enchants")) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@ -106,7 +117,7 @@ public class EnchantUtils {
|
||||
}
|
||||
|
||||
return compound.getKeys().stream().filter(key -> instance.getEnchantManager().getValueUnsafe(key) != null)
|
||||
.collect(Collectors.toMap(key -> instance.getEnchantManager().getValueUnsafe(key), compound::getInteger));
|
||||
.collect(Collectors.toMap(key -> instance.getEnchantManager().getValueUnsafe(key), compound::getInt));
|
||||
}
|
||||
|
||||
public void handlePlayer(@NotNull Player player, @Nullable LivingEntity opponent, Event event, TriggerType triggerType) {
|
||||
@ -128,27 +139,27 @@ public class EnchantUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
NBTItem nbtItem = new NBTItem(itemStack);
|
||||
NBTItem nbtItem = NmsManager.getNbt().of(itemStack);
|
||||
|
||||
if (nbtItem.getCompound("enchants") == null || nbtItem.getCompound("enchants").getInteger(enchant.getIdentifier()) == null) {
|
||||
if (nbtItem.getCompound("enchants") == null) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
String format = enchant.getFormat().replace("{level}", "").trim();
|
||||
String text = format.isEmpty() ? enchant.getColoredIdentifier(false) : format;
|
||||
|
||||
nbtItem.getCompound("enchants").removeKey(enchant.getIdentifier());
|
||||
ItemBuilder output = new ItemBuilder(nbtItem.getItem());
|
||||
nbtItem.getCompound("enchants").remove(enchant.getIdentifier());
|
||||
ItemBuilder output = new ItemBuilder(nbtItem.finish());
|
||||
output.removeLore(TextUtils.formatText(text));
|
||||
return output.build();
|
||||
}
|
||||
|
||||
public int getMaximumEnchantsCanApplyItem(ItemStack itemStack ,Player p) {
|
||||
public int getMaximumEnchantsCanApplyItem(ItemStack itemStack, Player p) {
|
||||
int max;
|
||||
if (p.isOp()) return 100; // in theory no single item will have 100 enchantments at a time.
|
||||
if(instance.getFileManager().getConfiguration("items/item-limits").contains("limits." + itemStack.getType().toString())){
|
||||
if (instance.getFileManager().getConfiguration("items/item-limits").contains("limits." + itemStack.getType().toString())) {
|
||||
max = instance.getFileManager().getConfiguration("items/item-limits").getInt("limits." + itemStack.getType().toString());
|
||||
}else{
|
||||
} else {
|
||||
max = instance.getFileManager().getConfiguration("items/item-limits").getInt("default");
|
||||
}
|
||||
return max;
|
||||
|
@ -1,695 +0,0 @@
|
||||
package com.songoda.epicenchants.utils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/**
|
||||
* bStats collects some data for plugin authors.
|
||||
* <p>
|
||||
* Check out https://bStats.org/ to learn more about bStats!
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
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";
|
||||
|
||||
// Is bStats enabled on this server?
|
||||
private boolean enabled;
|
||||
|
||||
// Should failed requests be logged?
|
||||
private static boolean logFailedRequests;
|
||||
|
||||
// Should the sent data be logged?
|
||||
private static boolean logSentData;
|
||||
|
||||
// Should the response text be logged?
|
||||
private static boolean logResponseStatusText;
|
||||
|
||||
// The uuid of the server
|
||||
private static String serverUUID;
|
||||
|
||||
// The plugin
|
||||
private final Plugin 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(Plugin 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);
|
||||
// Should the sent data be logged?
|
||||
config.addDefault("logSentData", false);
|
||||
// Should the response text be logged?
|
||||
config.addDefault("logResponseStatusText", 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 blacklist 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
|
||||
enabled = config.getBoolean("enabled", true);
|
||||
serverUUID = config.getString("serverUuid");
|
||||
logFailedRequests = config.getBoolean("logFailedRequests", false);
|
||||
logSentData = config.getBoolean("logSentData", false);
|
||||
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||
|
||||
if (enabled) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if bStats is enabled.
|
||||
*
|
||||
* @return Whether bStats is enabled or not.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom chart.
|
||||
*
|
||||
* @param chart The chart to add.
|
||||
*/
|
||||
public void addCustomChart(CustomChart chart) {
|
||||
if (chart == null) {
|
||||
throw new IllegalArgumentException("Chart cannot be null!");
|
||||
}
|
||||
charts.add(chart);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, () -> 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 blacklist 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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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 = Bukkit.getVersion();
|
||||
|
||||
// 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.
|
||||
*/
|
||||
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(plugin, 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 plugin Any plugin. It's just used to get a logger instance.
|
||||
* @param data The data to send.
|
||||
* @throws Exception If the request failed.
|
||||
*/
|
||||
private static void sendData(Plugin plugin, 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!");
|
||||
}
|
||||
if (logSentData) {
|
||||
plugin.getLogger().info("Sending data to bStats: " + data.toString());
|
||||
}
|
||||
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();
|
||||
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
bufferedReader.close();
|
||||
if (logResponseStatusText) {
|
||||
plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(StandardCharsets.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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom simple pie.
|
||||
*/
|
||||
public static class SimplePie extends CustomChart {
|
||||
|
||||
private final Callable<String> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimplePie(String chartId, Callable<String> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
String value = callable.call();
|
||||
if (value == null || value.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("value", value);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom advanced pie.
|
||||
*/
|
||||
public static class AdvancedPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom drilldown pie.
|
||||
*/
|
||||
public static class DrilldownPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Map<String, Integer>>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Map<String, Integer>> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean reallyAllSkipped = true;
|
||||
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
|
||||
JSONObject value = new JSONObject();
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
|
||||
value.put(valueEntry.getKey(), valueEntry.getValue());
|
||||
allSkipped = false;
|
||||
}
|
||||
if (!allSkipped) {
|
||||
reallyAllSkipped = false;
|
||||
values.put(entryValues.getKey(), value);
|
||||
}
|
||||
}
|
||||
if (reallyAllSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom single line chart.
|
||||
*/
|
||||
public static class SingleLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Integer> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
int value = callable.call();
|
||||
if (value == 0) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("value", value);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom multi line chart.
|
||||
*/
|
||||
public static class MultiLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom simple bar chart.
|
||||
*/
|
||||
public static class SimpleBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
JSONArray categoryValues = new JSONArray();
|
||||
categoryValues.add(entry.getValue());
|
||||
values.put(entry.getKey(), categoryValues);
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom advanced bar chart.
|
||||
*/
|
||||
public static class AdvancedBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, int[]>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, int[]> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, int[]> entry : map.entrySet()) {
|
||||
if (entry.getValue().length == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
JSONArray categoryValues = new JSONArray();
|
||||
for (int categoryValue : entry.getValue()) {
|
||||
categoryValues.add(categoryValue);
|
||||
}
|
||||
values.put(entry.getKey(), categoryValues);
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package com.songoda.epicenchants.utils;
|
||||
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.objects.Group;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.objects.ItemBuilder;
|
||||
import com.songoda.epicenchants.utils.settings.Settings;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@ -24,8 +24,8 @@ public class SpecialItems {
|
||||
|
||||
public ItemStack getWhiteScroll(int amount) {
|
||||
NBTItem nbtItem = new ItemBuilder(instance.getFileManager().getConfiguration("items/special-items").getConfigurationSection("white-scroll")).nbt();
|
||||
nbtItem.setBoolean("white-scroll", true);
|
||||
ItemStack itemStack = nbtItem.getItem();
|
||||
nbtItem.set("white-scroll", true);
|
||||
ItemStack itemStack = nbtItem.finish();
|
||||
|
||||
itemStack.setAmount(amount);
|
||||
|
||||
@ -36,10 +36,10 @@ public class SpecialItems {
|
||||
int successRate = chance == -1 ? ThreadLocalRandom.current().nextInt(Settings.BLACK_MIN.getInt(), Settings.BLACK_MAX.getInt() + 1) : chance;
|
||||
NBTItem nbtItem = new ItemBuilder(instance.getFileManager().getConfiguration("items/special-items").getConfigurationSection("black-scroll"), of("success-rate", successRate)).nbt();
|
||||
|
||||
nbtItem.setBoolean("black-scroll", true);
|
||||
nbtItem.setInteger("success-rate", successRate);
|
||||
nbtItem.set("black-scroll", true);
|
||||
nbtItem.set("success-rate", successRate);
|
||||
|
||||
ItemStack itemStack = nbtItem.getItem();
|
||||
ItemStack itemStack = nbtItem.finish();
|
||||
|
||||
itemStack.setAmount(amount);
|
||||
|
||||
@ -51,15 +51,15 @@ public class SpecialItems {
|
||||
of("group-color", group.getColor()),
|
||||
of("group-name", group.getName())).nbt();
|
||||
|
||||
nbtItem.setBoolean("mystery-book", true);
|
||||
nbtItem.setString("group", group.getIdentifier());
|
||||
return nbtItem.getItem();
|
||||
nbtItem.set("mystery-book", true);
|
||||
nbtItem.set("group", group.getIdentifier());
|
||||
return nbtItem.finish();
|
||||
}
|
||||
|
||||
|
||||
public ItemStack getSecretDust(NBTItem book) {
|
||||
Group group = instance.getEnchantManager().getValueUnsafe(book.getString("enchant")).getGroup();
|
||||
return getSecretDust(group, (int) Math.floor(book.getInteger("success-rate") / 10.0));
|
||||
Group group = instance.getEnchantManager().getValueUnsafe(book.getNBTObject("enchant").asString()).getGroup();
|
||||
return getSecretDust(group, (int) Math.floor(book.getNBTObject("success-rate").asInt() / 10.0));
|
||||
}
|
||||
|
||||
public ItemStack getSecretDust(Group group, int max) {
|
||||
@ -69,11 +69,11 @@ public class SpecialItems {
|
||||
of("max-rate", max),
|
||||
of("min-rate", 0)).nbt();
|
||||
|
||||
nbtItem.setBoolean("secret-dust", true);
|
||||
nbtItem.setString("group", group.getIdentifier());
|
||||
nbtItem.setInteger("max-rate", max + 1);
|
||||
nbtItem.setInteger("min-rate", 1);
|
||||
return nbtItem.getItem();
|
||||
nbtItem.set("secret-dust", true);
|
||||
nbtItem.set("group", group.getIdentifier());
|
||||
nbtItem.set("max-rate", max + 1);
|
||||
nbtItem.set("min-rate", 1);
|
||||
return nbtItem.finish();
|
||||
}
|
||||
|
||||
public ItemStack getDust(Group group, @Nullable String type, int percentage, boolean command) {
|
||||
@ -109,14 +109,14 @@ public class SpecialItems {
|
||||
of("percentage", percentage)).nbt();
|
||||
|
||||
if (type.equalsIgnoreCase("mystery")) {
|
||||
return nbtItem.getItem();
|
||||
return nbtItem.finish();
|
||||
}
|
||||
|
||||
nbtItem.setBoolean("dust", true);
|
||||
nbtItem.setInteger("percentage", percentage);
|
||||
nbtItem.setString("group", group.getIdentifier());
|
||||
nbtItem.set("dust", true);
|
||||
nbtItem.set("percentage", percentage);
|
||||
nbtItem.set("group", group.getIdentifier());
|
||||
|
||||
return nbtItem.getItem();
|
||||
return nbtItem.finish();
|
||||
}
|
||||
|
||||
public String getWhiteScrollLore() {
|
||||
|
@ -1,769 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Base class representing NMS Compounds. For a standalone implementation check
|
||||
* {@link NBTContainer}
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTCompound {
|
||||
|
||||
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
|
||||
private final Lock readLock = readWriteLock.readLock();
|
||||
private final Lock writeLock = readWriteLock.writeLock();
|
||||
|
||||
private String compundName;
|
||||
private NBTCompound parent;
|
||||
|
||||
protected NBTCompound(NBTCompound owner, String name) {
|
||||
this.compundName = name;
|
||||
this.parent = owner;
|
||||
}
|
||||
|
||||
protected Lock getReadLock() {
|
||||
return readLock;
|
||||
}
|
||||
|
||||
protected Lock getWriteLock() {
|
||||
return writeLock;
|
||||
}
|
||||
|
||||
protected void saveCompound() {
|
||||
if (parent != null)
|
||||
parent.saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Compound name
|
||||
*/
|
||||
public String getName() {
|
||||
return compundName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The NMS Compound behind this Object
|
||||
*/
|
||||
public Object getCompound() {
|
||||
return parent.getCompound();
|
||||
}
|
||||
|
||||
protected void setCompound(Object compound) {
|
||||
parent.setCompound(compound);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The parent Compound
|
||||
*/
|
||||
public NBTCompound getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges all data from comp into this compound. This is done in one action, so
|
||||
* it also works with Tiles/Entities
|
||||
*
|
||||
* @param comp
|
||||
*/
|
||||
public void mergeCompound(NBTCompound comp) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.mergeOtherNBTCompound(this, comp);
|
||||
saveCompound();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setString(String key, String value) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_STRING, key, value);
|
||||
saveCompound();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
public String getString(String key) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return (String) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_STRING, key);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
protected String getContent(String key) {
|
||||
return NBTReflectionUtil.getContent(this, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setInteger(String key, Integer value) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_INT, key, value);
|
||||
saveCompound();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
public Integer getInteger(String key) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return (Integer) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_INT, key);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setDouble(String key, Double value) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_DOUBLE, key, value);
|
||||
saveCompound();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
public Double getDouble(String key) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return (Double) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_DOUBLE, key);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setByte(String key, Byte value) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_BYTE, key, value);
|
||||
saveCompound();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
public Byte getByte(String key) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return (Byte) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_BYTE, key);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setShort(String key, Short value) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_SHORT, key, value);
|
||||
saveCompound();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
public Short getShort(String key) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return (Short) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_SHORT, key);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setLong(String key, Long value) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_LONG, key, value);
|
||||
saveCompound();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
public Long getLong(String key) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return (Long) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_LONG, key);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setFloat(String key, Float value) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_FLOAT, key, value);
|
||||
saveCompound();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
public Float getFloat(String key) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return (Float) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_FLOAT, key);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setByteArray(String key, byte[] value) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_BYTEARRAY, key, value);
|
||||
saveCompound();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
public byte[] getByteArray(String key) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return (byte[]) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_BYTEARRAY, key);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setIntArray(String key, int[] value) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_INTARRAY, key, value);
|
||||
saveCompound();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
public int[] getIntArray(String key) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return (int[]) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_INTARRAY, key);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setBoolean(String key, Boolean value) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_BOOLEAN, key, value);
|
||||
saveCompound();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
protected void set(String key, Object val) {
|
||||
NBTReflectionUtil.set(this, key, val);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
public Boolean getBoolean(String key) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return (Boolean) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_BOOLEAN, key);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses Gson to store an {@link Serializable} Object
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setObject(String key, Object value) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.setObject(this, key, value);
|
||||
saveCompound();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses Gson to retrieve a stored Object
|
||||
*
|
||||
* @param key
|
||||
* @param type Class of the Object
|
||||
* @return The created Object or null if empty
|
||||
*/
|
||||
public <T> T getObject(String key, Class<T> type) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return NBTReflectionUtil.getObject(this, key, type);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an ItemStack as a compound under a given key
|
||||
*
|
||||
* @param key
|
||||
* @param item
|
||||
*/
|
||||
public void setItemStack(String key, ItemStack item) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
removeKey(key);
|
||||
addCompound(key).mergeCompound(NBTItem.convertItemtoNBT(item));
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an ItemStack that was saved at the given key
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public ItemStack getItemStack(String key) {
|
||||
try {
|
||||
readLock.lock();
|
||||
NBTCompound comp = getCompound(key);
|
||||
return NBTItem.convertNBTtoItem(comp);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setUUID(String key, UUID value) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_UUID, key, value);
|
||||
saveCompound();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
public UUID getUUID(String key) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return (UUID) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_UUID, key);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return True if the key is set
|
||||
*/
|
||||
public Boolean hasKey(String key) {
|
||||
try {
|
||||
readLock.lock();
|
||||
Boolean b = (Boolean) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_HAS_KEY, key);
|
||||
if (b == null)
|
||||
return false;
|
||||
return b;
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key Deletes the given Key
|
||||
*/
|
||||
public void removeKey(String key) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.remove(this, key);
|
||||
saveCompound();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Set of all stored Keys
|
||||
*/
|
||||
public Set<String> getKeys() {
|
||||
try {
|
||||
readLock.lock();
|
||||
return NBTReflectionUtil.getKeys(this);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a subCompound
|
||||
*
|
||||
* @param name Key to use
|
||||
* @return The subCompound Object
|
||||
*/
|
||||
public NBTCompound addCompound(String name) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
if (getType(name) == NBTType.NBTTagCompound)
|
||||
return getCompound(name);
|
||||
NBTReflectionUtil.addNBTTagCompound(this, name);
|
||||
NBTCompound comp = getCompound(name);
|
||||
if (comp == null)
|
||||
throw new NbtApiException("Error while adding Compound, got null!");
|
||||
saveCompound();
|
||||
return comp;
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The Compound instance or null
|
||||
*/
|
||||
public NBTCompound getCompound(String name) {
|
||||
try {
|
||||
readLock.lock();
|
||||
if (getType(name) != NBTType.NBTTagCompound)
|
||||
return null;
|
||||
NBTCompound next = new NBTCompound(this, name);
|
||||
if (NBTReflectionUtil.valideCompound(next))
|
||||
return next;
|
||||
return null;
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved String List
|
||||
*/
|
||||
public NBTList<String> getStringList(String name) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTList<String> list = NBTReflectionUtil.getList(this, name, NBTType.NBTTagString, String.class);
|
||||
saveCompound();
|
||||
return list;
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Integer List
|
||||
*/
|
||||
public NBTList<Integer> getIntegerList(String name) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTList<Integer> list = NBTReflectionUtil.getList(this, name, NBTType.NBTTagInt, Integer.class);
|
||||
saveCompound();
|
||||
return list;
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Float List
|
||||
*/
|
||||
public NBTList<Float> getFloatList(String name) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTList<Float> list = NBTReflectionUtil.getList(this, name, NBTType.NBTTagFloat, Float.class);
|
||||
saveCompound();
|
||||
return list;
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Double List
|
||||
*/
|
||||
public NBTList<Double> getDoubleList(String name) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTList<Double> list = NBTReflectionUtil.getList(this, name, NBTType.NBTTagDouble, Double.class);
|
||||
saveCompound();
|
||||
return list;
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Long List
|
||||
*/
|
||||
public NBTList<Long> getLongList(String name) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTList<Long> list = NBTReflectionUtil.getList(this, name, NBTType.NBTTagLong, Long.class);
|
||||
saveCompound();
|
||||
return list;
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Compound List
|
||||
*/
|
||||
public NBTCompoundList getCompoundList(String name) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTCompoundList list = (NBTCompoundList) NBTReflectionUtil.getList(this, name, NBTType.NBTTagCompound,
|
||||
NBTListCompound.class);
|
||||
saveCompound();
|
||||
return list;
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The type of the given stored key or null
|
||||
*/
|
||||
public NBTType getType(String name) {
|
||||
try {
|
||||
readLock.lock();
|
||||
if (MinecraftVersion.getVersion() == MinecraftVersion.MC1_7_R4) {
|
||||
Object nbtbase = NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET, name);
|
||||
if(nbtbase == null)
|
||||
return null;
|
||||
return NBTType.valueOf((byte)ReflectionMethod.COMPOUND_OWN_TYPE.run(nbtbase));
|
||||
}
|
||||
Object o = NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_TYPE, name);
|
||||
if (o == null)
|
||||
return null;
|
||||
return NBTType.valueOf((byte) o);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void writeCompound(OutputStream stream) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
NBTReflectionUtil.writeApiNBT(this, stream);
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
/*
|
||||
* StringBuilder result = new StringBuilder(); for (String key : getKeys()) {
|
||||
* result.append(toString(key)); } return result.toString();
|
||||
*/
|
||||
return asNBTString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Just use toString()
|
||||
* @param key
|
||||
* @return A string representation of the given key
|
||||
*/
|
||||
@Deprecated
|
||||
public String toString(String key) {
|
||||
/*
|
||||
* StringBuilder result = new StringBuilder(); NBTCompound compound = this;
|
||||
* while (compound.getParent() != null) { result.append(" "); compound =
|
||||
* compound.getParent(); } if (this.getType(key) == NBTType.NBTTagCompound) {
|
||||
* return this.getCompound(key).toString(); } else { return result + "-" + key +
|
||||
* ": " + getContent(key) + System.lineSeparator(); }
|
||||
*/
|
||||
return asNBTString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Just use toString()
|
||||
* @return A {@link String} representation of the NBT in Mojang JSON. This is different from normal JSON!
|
||||
*/
|
||||
@Deprecated
|
||||
public String asNBTString() {
|
||||
try {
|
||||
readLock.lock();
|
||||
Object comp = NBTReflectionUtil.gettoCompount(getCompound(), this);
|
||||
if (comp == null)
|
||||
return "{}";
|
||||
return comp.toString();
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return toString().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the nbt-string to match this compound with another object. This allows
|
||||
* two "technically" different Compounds to match, if they have the same content
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
return toString().equals(obj.toString());
|
||||
}
|
||||
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import org.apache.commons.lang.NotImplementedException;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* {@link NBTListCompound} implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTCompoundList extends NBTList<NBTListCompound> {
|
||||
|
||||
protected NBTCompoundList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
super(owner, name, type, list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new Compound to the end of the List and returns it.
|
||||
*
|
||||
* @return The added {@link NBTListCompound}
|
||||
*/
|
||||
public NBTListCompound addCompound() {
|
||||
return (NBTListCompound) addCompound(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a copy of the Compound to the end of the List and returns it.
|
||||
* When null is given, a new Compound will be created
|
||||
*
|
||||
* @param comp
|
||||
* @return
|
||||
*/
|
||||
public NBTCompound addCompound(NBTCompound comp) {
|
||||
try {
|
||||
Object compound = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
|
||||
ReflectionMethod.LIST_ADD.run(listObject, size(), compound);
|
||||
} else {
|
||||
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, compound);
|
||||
}
|
||||
getParent().saveCompound();
|
||||
NBTListCompound listcomp = new NBTListCompound(this, compound);
|
||||
if(comp != null){
|
||||
listcomp.mergeCompound(comp);
|
||||
}
|
||||
return listcomp;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new Compound to the end of the List.
|
||||
*
|
||||
*
|
||||
* @deprecated Please use addCompound!
|
||||
* @param empty
|
||||
* @return True, if compound was added
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean add(NBTListCompound empty) {
|
||||
return addCompound(empty) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, NBTListCompound element) {
|
||||
if (element != null) {
|
||||
throw new NotImplementedException("You need to pass null! ListCompounds from other lists won't work.");
|
||||
}
|
||||
try {
|
||||
Object compound = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
|
||||
ReflectionMethod.LIST_ADD.run(listObject, index, compound);
|
||||
} else {
|
||||
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, compound);
|
||||
}
|
||||
super.getParent().saveCompound();
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTListCompound get(int index) {
|
||||
try {
|
||||
Object compound = ReflectionMethod.LIST_GET_COMPOUND.run(listObject, index);
|
||||
return new NBTListCompound(this, compound);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTListCompound set(int index, NBTListCompound element) {
|
||||
throw new NotImplementedException("This method doesn't work in the ListCompound context.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object asTag(NBTListCompound object) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ObjectCreator;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* A Standalone {@link NBTCompound} implementation. All data is just kept inside
|
||||
* this Object.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTContainer extends NBTCompound {
|
||||
|
||||
private Object nbt;
|
||||
|
||||
/**
|
||||
* Creates an empty, standalone NBTCompound
|
||||
*/
|
||||
public NBTContainer() {
|
||||
super(null, null);
|
||||
nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes in any NMS Compound to wrap it
|
||||
*
|
||||
* @param nbt
|
||||
*/
|
||||
public NBTContainer(Object nbt) {
|
||||
super(null, null);
|
||||
if (nbt == null) {
|
||||
throw new NullPointerException("The NBT-Object can't be null!");
|
||||
}
|
||||
if (!ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().isAssignableFrom(nbt.getClass())) {
|
||||
throw new NbtApiException("The object '" + nbt.getClass() + "' is not a valid NBT-Object!");
|
||||
}
|
||||
this.nbt = nbt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in a NBT InputStream
|
||||
*
|
||||
* @param inputsteam
|
||||
*/
|
||||
public NBTContainer(InputStream inputsteam) {
|
||||
super(null, null);
|
||||
this.nbt = NBTReflectionUtil.readNBT(inputsteam);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses in a NBT String to a standalone {@link NBTCompound}. Can throw a
|
||||
* {@link NbtApiException} in case something goes wrong.
|
||||
*
|
||||
* @param nbtString
|
||||
*/
|
||||
public NBTContainer(String nbtString) {
|
||||
super(null, null);
|
||||
if (nbtString == null) {
|
||||
throw new NullPointerException("The String can't be null!");
|
||||
}
|
||||
try {
|
||||
nbt = ReflectionMethod.PARSE_NBT.run(null, nbtString);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Unable to parse Malformed Json!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompound(Object tag) {
|
||||
nbt = tag;
|
||||
}
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Double implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTDoubleList extends NBTList<Double> {
|
||||
|
||||
protected NBTDoubleList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
super(owner, name, type, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object asTag(Double object) {
|
||||
try {
|
||||
Constructor<?> con = ClassWrapper.NMS_NBTTAGDOUBLE.getClazz().getDeclaredConstructor(double.class);
|
||||
con.setAccessible(true);
|
||||
return con.newInstance(object);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
||||
| NoSuchMethodException | SecurityException e) {
|
||||
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double get(int index) {
|
||||
try {
|
||||
Object obj = ReflectionMethod.LIST_GET.run(listObject, index);
|
||||
return Double.valueOf(obj.toString());
|
||||
} catch (NumberFormatException nf) {
|
||||
return 0d;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.annotations.AvaliableSince;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.annotations.CheckUtil;
|
||||
|
||||
/**
|
||||
* NBT class to access vanilla tags from Entities. Entities don't support custom
|
||||
* tags. Use the NBTInjector for custom tags. Changes will be instantly applied
|
||||
* to the Entity, use the merge method to do many things at once.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTEntity extends NBTCompound {
|
||||
|
||||
private final Entity ent;
|
||||
|
||||
/**
|
||||
* @param entity Any valid Bukkit Entity
|
||||
*/
|
||||
public NBTEntity(Entity entity) {
|
||||
super(null, null);
|
||||
if (entity == null) {
|
||||
throw new NullPointerException("Entity can't be null!");
|
||||
}
|
||||
ent = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return NBTReflectionUtil.getEntityNBTTagCompound(NBTReflectionUtil.getNMSEntity(ent));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCompound(Object compound) {
|
||||
NBTReflectionUtil.setEntityNBTTag(compound, NBTReflectionUtil.getNMSEntity(ent));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the NBTCompound used by spigots PersistentDataAPI. This method is only
|
||||
* available for 1.14+!
|
||||
*
|
||||
* @return NBTCompound containing the data of the PersistentDataAPI
|
||||
*/
|
||||
@AvaliableSince(version = MinecraftVersion.MC1_14_R1)
|
||||
public NBTCompound getPersistentDataContainer() {
|
||||
if (hasKey("BukkitValues")) {
|
||||
return getCompound("BukkitValues");
|
||||
} else {
|
||||
NBTContainer container = new NBTContainer();
|
||||
container.addCompound("BukkitValues").setString("__nbtapi",
|
||||
"Marker to make the PersistentDataContainer have content");
|
||||
mergeCompound(container);
|
||||
return getCompound("BukkitValues");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ObjectCreator;
|
||||
|
||||
/**
|
||||
* {@link NBTCompound} implementation backed by a {@link File}
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTFile extends NBTCompound {
|
||||
|
||||
private final File file;
|
||||
private Object nbt;
|
||||
|
||||
/**
|
||||
* Creates a NBTFile that uses @param file to store it's data. If this file
|
||||
* exists, the data will be loaded.
|
||||
*
|
||||
* @param file
|
||||
* @throws IOException
|
||||
*/
|
||||
public NBTFile(File file) throws IOException {
|
||||
super(null, null);
|
||||
if (file == null) {
|
||||
throw new NullPointerException("File can't be null!");
|
||||
}
|
||||
this.file = file;
|
||||
if (file.exists()) {
|
||||
FileInputStream inputsteam = new FileInputStream(file);
|
||||
nbt = NBTReflectionUtil.readNBT(inputsteam);
|
||||
} else {
|
||||
nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the data to the file
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void save() throws IOException {
|
||||
try {
|
||||
getWriteLock().lock();
|
||||
if (!file.exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
if (!file.createNewFile())
|
||||
throw new IOException("Unable to create file at " + file.getAbsolutePath());
|
||||
}
|
||||
FileOutputStream outStream = new FileOutputStream(file);
|
||||
NBTReflectionUtil.writeNBT(nbt, outStream);
|
||||
} finally {
|
||||
getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The File used to store the data
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCompound(Object compound) {
|
||||
nbt = compound;
|
||||
}
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Float implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTFloatList extends NBTList<Float> {
|
||||
|
||||
protected NBTFloatList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
super(owner, name, type, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object asTag(Float object) {
|
||||
try {
|
||||
Constructor<?> con = ClassWrapper.NMS_NBTTAGFLOAT.getClazz().getDeclaredConstructor(float.class);
|
||||
con.setAccessible(true);
|
||||
return con.newInstance(object);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
||||
| NoSuchMethodException | SecurityException e) {
|
||||
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(int index) {
|
||||
try {
|
||||
Object obj = ReflectionMethod.LIST_GET.run(listObject, index);
|
||||
return Float.valueOf(obj.toString());
|
||||
} catch (NumberFormatException nf) {
|
||||
return 0f;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ObjectCreator;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
public class NBTGameProfile {
|
||||
|
||||
/**
|
||||
* Convert a GameProfile to NBT. The NBT then can be modified or be stored
|
||||
*
|
||||
* @param profile
|
||||
* @return A NBTContainer with all the GameProfile data
|
||||
*/
|
||||
public static NBTCompound toNBT(GameProfile profile) {
|
||||
return new NBTContainer(ReflectionMethod.GAMEPROFILE_SERIALIZE.run(null, ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance(), profile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstructs a GameProfile from a NBTCompound
|
||||
*
|
||||
* @param compound Has to contain GameProfile data
|
||||
* @return The reconstructed GameProfile
|
||||
*/
|
||||
public static GameProfile fromNBT(NBTCompound compound) {
|
||||
return (GameProfile) ReflectionMethod.GAMEPROFILE_DESERIALIZE.run(null, NBTReflectionUtil.gettoCompount(compound.getCompound(), compound));
|
||||
}
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Integer implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTIntegerList extends NBTList<Integer> {
|
||||
|
||||
protected NBTIntegerList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
super(owner, name, type, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object asTag(Integer object) {
|
||||
try {
|
||||
Constructor<?> con = ClassWrapper.NMS_NBTTAGINT.getClazz().getDeclaredConstructor(int.class);
|
||||
con.setAccessible(true);
|
||||
return con.newInstance(object);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
||||
| NoSuchMethodException | SecurityException e) {
|
||||
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer get(int index) {
|
||||
try {
|
||||
Object obj = ReflectionMethod.LIST_GET.run(listObject, index);
|
||||
return Integer.valueOf(obj.toString());
|
||||
} catch (NumberFormatException nf) {
|
||||
return 0;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,165 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* NBT class to access vanilla/custom tags on ItemStacks. This class doesn't
|
||||
* autosave to the Itemstack, use getItem to get the changed ItemStack
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTItem extends NBTCompound {
|
||||
|
||||
private ItemStack bukkitItem;
|
||||
private boolean directApply;
|
||||
private ItemStack originalSrcStack = null;
|
||||
|
||||
/**
|
||||
* Constructor for NBTItems. The ItemStack will be cloned!
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
public NBTItem(ItemStack item) {
|
||||
this(item, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for NBTItems. The ItemStack will be cloned! If directApply is true,
|
||||
* all changed will be mapped to the original item. Changes to the NBTItem will overwrite changes done
|
||||
* to the original item in that case.
|
||||
*
|
||||
* @param item
|
||||
* @param directApply
|
||||
*/
|
||||
public NBTItem(ItemStack item, boolean directApply) {
|
||||
super(null, null);
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
throw new NullPointerException("ItemStack can't be null/Air!");
|
||||
}
|
||||
this.directApply = directApply;
|
||||
bukkitItem = item.clone();
|
||||
if(directApply) {
|
||||
this.originalSrcStack = item;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return NBTReflectionUtil.getItemRootNBTTagCompound(ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCompound(Object compound) {
|
||||
Object stack = ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem);
|
||||
ReflectionMethod.ITEMSTACK_SET_TAG.run(stack, compound);
|
||||
bukkitItem = (ItemStack) ReflectionMethod.ITEMSTACK_BUKKITMIRROR.run(null, stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply stored NBT tags to the provided ItemStack.
|
||||
* <p>
|
||||
* Note: This will completely override current item's {@link ItemMeta}.
|
||||
* If you still want to keep the original item's NBT tags, see
|
||||
* {@link #mergeNBT(ItemStack)} and {@link #mergeCustomNBT(ItemStack)}.
|
||||
*
|
||||
* @param item ItemStack that should get the new NBT data
|
||||
*/
|
||||
public void applyNBT(ItemStack item) {
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
throw new NullPointerException("ItemStack can't be null/Air!");
|
||||
}
|
||||
NBTItem nbti = new NBTItem(new ItemStack(item.getType()));
|
||||
nbti.mergeCompound(this);
|
||||
item.setItemMeta(nbti.getItem().getItemMeta());
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge all NBT tags to the provided ItemStack.
|
||||
*
|
||||
* @param item ItemStack that should get the new NBT data
|
||||
*/
|
||||
public void mergeNBT(ItemStack item) {
|
||||
NBTItem nbti = new NBTItem(item);
|
||||
nbti.mergeCompound(this);
|
||||
item.setItemMeta(nbti.getItem().getItemMeta());
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge only custom (non-vanilla) NBT tags to the provided ItemStack.
|
||||
*
|
||||
* @param item ItemStack that should get the new NBT data
|
||||
*/
|
||||
public void mergeCustomNBT(ItemStack item) {
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
throw new NullPointerException("ItemStack can't be null/Air!");
|
||||
}
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
NBTReflectionUtil.getUnhandledNBTTags(meta).putAll(NBTReflectionUtil.getUnhandledNBTTags(bukkitItem.getItemMeta()));
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all custom (non-vanilla) NBT tags from the NBTItem.
|
||||
*/
|
||||
public void clearCustomNBT() {
|
||||
ItemMeta meta = bukkitItem.getItemMeta();
|
||||
NBTReflectionUtil.getUnhandledNBTTags(meta).clear();
|
||||
bukkitItem.setItemMeta(meta);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The modified ItemStack
|
||||
*/
|
||||
public ItemStack getItem() {
|
||||
return bukkitItem;
|
||||
}
|
||||
|
||||
protected void setItem(ItemStack item) {
|
||||
bukkitItem = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* This may return true even when the NBT is empty.
|
||||
*
|
||||
* @return Does the ItemStack have a NBTCompound.
|
||||
*/
|
||||
public boolean hasNBTData() {
|
||||
return getCompound() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that converts {@link ItemStack} to {@link NBTContainer} with
|
||||
* all it's data like Material, Damage, Amount and Tags.
|
||||
*
|
||||
* @param item
|
||||
* @return Standalone {@link NBTContainer} with the Item's data
|
||||
*/
|
||||
public static NBTContainer convertItemtoNBT(ItemStack item) {
|
||||
return NBTReflectionUtil.convertNMSItemtoNBTCompound(ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, item));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to do the inverse to "convertItemtoNBT". Creates an
|
||||
* {@link ItemStack} using the {@link NBTCompound}
|
||||
*
|
||||
* @param comp
|
||||
* @return ItemStack using the {@link NBTCompound}'s data
|
||||
*/
|
||||
public static ItemStack convertNBTtoItem(NBTCompound comp) {
|
||||
return (ItemStack) ReflectionMethod.ITEMSTACK_BUKKITMIRROR.run(null,
|
||||
NBTReflectionUtil.convertNBTCompoundtoNMSItem(comp));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveCompound() {
|
||||
if(directApply) {
|
||||
applyNBT(originalSrcStack);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,429 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Abstract List implementation for ListCompounds
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class NBTList<T> implements List<T> {
|
||||
|
||||
private String listName;
|
||||
private NBTCompound parent;
|
||||
private NBTType type;
|
||||
protected Object listObject;
|
||||
|
||||
protected NBTList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
parent = owner;
|
||||
listName = name;
|
||||
this.type = type;
|
||||
this.listObject = list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Name of this list-compound
|
||||
*/
|
||||
public String getName() {
|
||||
return listName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Compound's parent Object
|
||||
*/
|
||||
public NBTCompound getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
protected void save() {
|
||||
parent.set(listName, listObject);
|
||||
}
|
||||
|
||||
protected abstract Object asTag(T object);
|
||||
|
||||
@Override
|
||||
public boolean add(T element) {
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
|
||||
ReflectionMethod.LIST_ADD.run(listObject, size(), asTag(element));
|
||||
} else {
|
||||
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, asTag(element));
|
||||
}
|
||||
save();
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, T element) {
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
|
||||
ReflectionMethod.LIST_ADD.run(listObject, index, asTag(element));
|
||||
} else {
|
||||
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, asTag(element));
|
||||
}
|
||||
save();
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T set(int index, T element) {
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
T prev = get(index);
|
||||
ReflectionMethod.LIST_SET.run(listObject, index, asTag(element));
|
||||
save();
|
||||
return prev;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public T remove(int i) {
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
T old = get(i);
|
||||
ReflectionMethod.LIST_REMOVE_KEY.run(listObject, i);
|
||||
save();
|
||||
return old;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
return (int) ReflectionMethod.LIST_SIZE.run(listObject);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The type that this list contains
|
||||
*/
|
||||
public NBTType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
while (!isEmpty()) {
|
||||
remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (o.equals(get(i)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (o.equals(get(i)))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends T> c) {
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
int size = size();
|
||||
for (T ele : c) {
|
||||
add(ele);
|
||||
}
|
||||
return size != size();
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, Collection<? extends T> c) {
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
int size = size();
|
||||
for (T ele : c) {
|
||||
add(index++, ele);
|
||||
}
|
||||
return size != size();
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
for (Object ele : c) {
|
||||
if (!contains(ele))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
int index = -1;
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (o.equals(get(i)))
|
||||
index = i;
|
||||
}
|
||||
return index;
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
int size = size();
|
||||
for (Object obj : c) {
|
||||
remove(obj);
|
||||
}
|
||||
return size != size();
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
int size = size();
|
||||
for (Object obj : c) {
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (!obj.equals(get(i))) {
|
||||
remove(i--);
|
||||
}
|
||||
}
|
||||
}
|
||||
return size != size();
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
int size = size();
|
||||
int id = -1;
|
||||
while ((id = indexOf(o)) != -1) {
|
||||
remove(id);
|
||||
}
|
||||
return size != size();
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new Iterator<T>() {
|
||||
|
||||
private int index = -1;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return size() > index + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
return get(++index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
NBTList.this.remove(index);
|
||||
index--;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<T> listIterator() {
|
||||
return listIterator(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<T> listIterator(int startIndex) {
|
||||
final NBTList<T> list = this;
|
||||
return new ListIterator<T>() {
|
||||
|
||||
int index = startIndex - 1;
|
||||
|
||||
@Override
|
||||
public void add(T e) {
|
||||
list.add(index, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return size() > index + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return index >= 0 && index <= size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
return get(++index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T previous() {
|
||||
if (!hasPrevious())
|
||||
throw new NoSuchElementException("Id: " + (index - 1));
|
||||
return get(index--);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return index - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
list.remove(index);
|
||||
index--;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(T e) {
|
||||
list.set(index, e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
Object[] ar = new Object[size()];
|
||||
for (int i = 0; i < size(); i++)
|
||||
ar[i] = get(i);
|
||||
return ar;
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <E> E[] toArray(E[] a) {
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
E[] ar = Arrays.copyOf(a, size());
|
||||
Arrays.fill(ar, null);
|
||||
Class<?> arrayclass = a.getClass().getComponentType();
|
||||
for (int i = 0; i < size(); i++) {
|
||||
T obj = get(i);
|
||||
if (arrayclass.isInstance(obj)) {
|
||||
ar[i] = (E) get(i);
|
||||
} else {
|
||||
throw new ArrayStoreException("The array does not match the objects stored in the List.");
|
||||
}
|
||||
}
|
||||
return ar;
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> subList(int fromIndex, int toIndex) {
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
ArrayList<T> list = new ArrayList<>();
|
||||
for (int i = fromIndex; i < toIndex; i++)
|
||||
list.add(get(i));
|
||||
return list;
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
return listObject.toString();
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
/**
|
||||
* Cut down version of the {@link NBTCompound} for inside
|
||||
* {@link NBTCompoundList} This Compound implementation is missing the ability
|
||||
* for further subCompounds and Lists. This class probably will change in the
|
||||
* future
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTListCompound extends NBTCompound {
|
||||
|
||||
private NBTList<?> owner;
|
||||
private Object compound;
|
||||
|
||||
protected NBTListCompound(NBTList<?> parent, Object obj) {
|
||||
super(null, null);
|
||||
owner = parent;
|
||||
compound = obj;
|
||||
}
|
||||
|
||||
public NBTList<?> getListParent() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return compound;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCompound(Object compound) {
|
||||
this.compound = compound;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveCompound() {
|
||||
owner.save();
|
||||
}
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Long implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTLongList extends NBTList<Long> {
|
||||
|
||||
protected NBTLongList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
super(owner, name, type, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object asTag(Long object) {
|
||||
try {
|
||||
Constructor<?> con = ClassWrapper.NMS_NBTTAGLONG.getClazz().getDeclaredConstructor(long.class);
|
||||
con.setAccessible(true);
|
||||
return con.newInstance(object);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
||||
| NoSuchMethodException | SecurityException e) {
|
||||
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long get(int index) {
|
||||
try {
|
||||
Object obj = ReflectionMethod.LIST_GET.run(listObject, index);
|
||||
return Long.valueOf(obj.toString().replace("L", ""));
|
||||
} catch (NumberFormatException nf) {
|
||||
return 0l;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,578 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.GsonWrapper;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ObjectCreator;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Utility class for translating NBTApi calls to reflections into NMS code All
|
||||
* methods are allowed to throw {@link NbtApiException}
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTReflectionUtil {
|
||||
|
||||
private static Field field_unhandledTags = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
field_unhandledTags = ClassWrapper.CRAFT_METAITEM.getClazz().getDeclaredField("unhandledTags");
|
||||
field_unhandledTags.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hidden constructor
|
||||
*/
|
||||
private NBTReflectionUtil() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the NMS Entity for a given Bukkit Entity
|
||||
*
|
||||
* @param entity Bukkit Entity
|
||||
* @return NMS Entity
|
||||
*/
|
||||
public static Object getNMSEntity(Entity entity) {
|
||||
try {
|
||||
return ReflectionMethod.CRAFT_ENTITY_GET_HANDLE.run(ClassWrapper.CRAFT_ENTITY.getClazz().cast(entity));
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while getting the NMS Entity from a Bukkit Entity!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in a InputStream as NMS Compound
|
||||
*
|
||||
* @param stream InputStream of any NBT file
|
||||
* @return NMS Compound
|
||||
*/
|
||||
public static Object readNBT(InputStream stream) {
|
||||
try {
|
||||
return ReflectionMethod.NBTFILE_READ.run(null, stream);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while reading a NBT File!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a NMS Compound to an OutputStream
|
||||
*
|
||||
* @param nbt NMS Compound
|
||||
* @param stream Stream to write to
|
||||
* @return ???
|
||||
*/
|
||||
public static Object writeNBT(Object nbt, OutputStream stream) {
|
||||
try {
|
||||
return ReflectionMethod.NBTFILE_WRITE.run(null, nbt, stream);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while writing NBT!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a Compound to an OutputStream
|
||||
*
|
||||
* @param comp Compound
|
||||
* @param stream Stream to write to
|
||||
*/
|
||||
public static void writeApiNBT(NBTCompound comp, OutputStream stream) {
|
||||
try {
|
||||
Object nbttag = comp.getCompound();
|
||||
if (nbttag == null) {
|
||||
nbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp))
|
||||
return;
|
||||
Object workingtag = gettoCompount(nbttag, comp);
|
||||
ReflectionMethod.NBTFILE_WRITE.run(null, workingtag, stream);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while writing NBT!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates getOrCreateTag. If an Item doesn't yet have a Tag, it will return a
|
||||
* new empty tag.
|
||||
*
|
||||
* @param nmsitem
|
||||
* @return NMS Compound
|
||||
*/
|
||||
public static Object getItemRootNBTTagCompound(Object nmsitem) {
|
||||
try {
|
||||
Object answer = ReflectionMethod.NMSITEM_GETTAG.run(nmsitem);
|
||||
return answer != null ? answer : ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while getting an Itemstack's NBTCompound!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts {@link NBTCompound} to NMS ItemStacks
|
||||
*
|
||||
* @param nbtcompound Any valid {@link NBTCompound}
|
||||
* @return NMS ItemStack
|
||||
*/
|
||||
public static Object convertNBTCompoundtoNMSItem(NBTCompound nbtcompound) {
|
||||
try {
|
||||
Object nmsComp = gettoCompount(nbtcompound.getCompound(), nbtcompound);
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_11_R1.getVersionId()) {
|
||||
return ObjectCreator.NMS_COMPOUNDFROMITEM.getInstance(nmsComp);
|
||||
} else {
|
||||
return ReflectionMethod.NMSITEM_CREATESTACK.run(null, nmsComp);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while converting NBTCompound to NMS ItemStack!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts NMS ItemStacks to {@link NBTContainer}
|
||||
*
|
||||
* @param nmsitem NMS ItemStack
|
||||
* @return {@link NBTContainer} with all the data
|
||||
*/
|
||||
public static NBTContainer convertNMSItemtoNBTCompound(Object nmsitem) {
|
||||
try {
|
||||
Object answer = ReflectionMethod.NMSITEM_SAVE.run(nmsitem, ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance());
|
||||
return new NBTContainer(answer);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while converting NMS ItemStack to NBTCompound!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a live copy of non-vanilla NBT tags.
|
||||
*
|
||||
* @param meta ItemMeta from which tags should be retrieved
|
||||
* @return Map containing unhandled (custom) NBT tags
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Object> getUnhandledNBTTags(ItemMeta meta) {
|
||||
try {
|
||||
return (Map<String, Object>) field_unhandledTags.get(meta);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while getting unhandled tags from ItemMeta!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Vanilla NBT Compound from a given NMS Entity
|
||||
*
|
||||
* @param nmsEntity
|
||||
* @return NMS NBT Compound
|
||||
*/
|
||||
public static Object getEntityNBTTagCompound(Object nmsEntity) {
|
||||
try {
|
||||
Object nbt = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
||||
Object answer = ReflectionMethod.NMS_ENTITY_GET_NBT.run(nmsEntity, nbt);
|
||||
if (answer == null)
|
||||
answer = nbt;
|
||||
return answer;
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while getting NBTCompound from NMS Entity!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all Vanilla tags from a NMS Compound into a NMS Entity
|
||||
*
|
||||
* @param nbtTag
|
||||
* @param nmsEntity
|
||||
* @return The NMS Entity
|
||||
*/
|
||||
public static Object setEntityNBTTag(Object nbtTag, Object nmsEntity) {
|
||||
try {
|
||||
ReflectionMethod.NMS_ENTITY_SET_NBT.run(nmsEntity, nbtTag);
|
||||
return nmsEntity;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Exception while setting the NBTCompound of an Entity", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the NMS Compound from a given TileEntity
|
||||
*
|
||||
* @param tile
|
||||
* @return NMS Compound with the Vanilla data
|
||||
*/
|
||||
public static Object getTileEntityNBTTagCompound(BlockState tile) {
|
||||
try {
|
||||
Object cworld = ClassWrapper.CRAFT_WORLD.getClazz().cast(tile.getWorld());
|
||||
Object nmsworld = ReflectionMethod.CRAFT_WORLD_GET_HANDLE.run(cworld);
|
||||
Object o = null;
|
||||
if(MinecraftVersion.getVersion() == MinecraftVersion.MC1_7_R4) {
|
||||
o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY_1_7_10.run(nmsworld, tile.getX(), tile.getY(), tile.getZ());
|
||||
}else {
|
||||
Object pos = ObjectCreator.NMS_BLOCKPOSITION.getInstance(tile.getX(), tile.getY(), tile.getZ());
|
||||
o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY.run(nmsworld, pos);
|
||||
}
|
||||
Object tag = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
||||
Object answer = ReflectionMethod.TILEENTITY_GET_NBT.run(o, tag);
|
||||
if (answer == null)
|
||||
answer = tag;
|
||||
return answer;
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while getting NBTCompound from TileEntity!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets Vanilla tags from a NMS Compound to a TileEntity
|
||||
*
|
||||
* @param tile
|
||||
* @param comp
|
||||
*/
|
||||
public static void setTileEntityNBTTagCompound(BlockState tile, Object comp) {
|
||||
try {
|
||||
Object cworld = ClassWrapper.CRAFT_WORLD.getClazz().cast(tile.getWorld());
|
||||
Object nmsworld = ReflectionMethod.CRAFT_WORLD_GET_HANDLE.run(cworld);
|
||||
Object o = null;
|
||||
if(MinecraftVersion.getVersion() == MinecraftVersion.MC1_7_R4) {
|
||||
o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY_1_7_10.run(nmsworld, tile.getX(), tile.getY(), tile.getZ());
|
||||
}else {
|
||||
Object pos = ObjectCreator.NMS_BLOCKPOSITION.getInstance(tile.getX(), tile.getY(), tile.getZ());
|
||||
o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY.run(nmsworld, pos);
|
||||
}
|
||||
if(MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_16_R1.getVersionId()) {
|
||||
Object blockData = ReflectionMethod.TILEENTITY_GET_BLOCKDATA.run(o);
|
||||
ReflectionMethod.TILEENTITY_SET_NBT.run(o, blockData, comp);
|
||||
}else {
|
||||
ReflectionMethod.TILEENTITY_SET_NBT_LEGACY1151.run(o, comp);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while setting NBTData for a TileEntity!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the subCompound with a given name from a NMS Compound
|
||||
*
|
||||
* @param compound
|
||||
* @param name
|
||||
* @return NMS Compound or null
|
||||
*/
|
||||
public static Object getSubNBTTagCompound(Object compound, String name) {
|
||||
try {
|
||||
if ((boolean) ReflectionMethod.COMPOUND_HAS_KEY.run(compound, name)) {
|
||||
return ReflectionMethod.COMPOUND_GET_COMPOUND.run(compound, name);
|
||||
} else {
|
||||
throw new NbtApiException("Tried getting invalide compound '" + name + "' from '" + compound + "'!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while getting NBT subcompounds!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a subCompound with a given name in the given NMS Compound
|
||||
*
|
||||
* @param comp
|
||||
* @param name
|
||||
*/
|
||||
public static void addNBTTagCompound(NBTCompound comp, String name) {
|
||||
if (name == null) {
|
||||
remove(comp, name);
|
||||
return;
|
||||
}
|
||||
Object nbttag = comp.getCompound();
|
||||
if (nbttag == null) {
|
||||
nbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp)) {
|
||||
return;
|
||||
}
|
||||
Object workingtag = gettoCompount(nbttag, comp);
|
||||
try {
|
||||
ReflectionMethod.COMPOUND_SET.run(workingtag, name,
|
||||
ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance());
|
||||
comp.setCompound(nbttag);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while adding a Compound!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the Compound is correctly linked to it's roots
|
||||
*
|
||||
* @param comp
|
||||
* @return true if this is a valide Compound, else false
|
||||
*/
|
||||
public static Boolean valideCompound(NBTCompound comp) {
|
||||
Object root = comp.getCompound();
|
||||
if (root == null) {
|
||||
root = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
return (gettoCompount(root, comp)) != null;
|
||||
}
|
||||
|
||||
protected static Object gettoCompount(Object nbttag, NBTCompound comp) {
|
||||
Deque<String> structure = new ArrayDeque<>();
|
||||
while (comp.getParent() != null) {
|
||||
structure.add(comp.getName());
|
||||
comp = comp.getParent();
|
||||
}
|
||||
while (!structure.isEmpty()) {
|
||||
String target = structure.pollLast();
|
||||
nbttag = getSubNBTTagCompound(nbttag, target);
|
||||
if (nbttag == null) {
|
||||
throw new NbtApiException("Unable to find tag '" + target + "' in " + nbttag);
|
||||
}
|
||||
}
|
||||
return nbttag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the second {@link NBTCompound} into the first one
|
||||
*
|
||||
* @param comp Target for the merge
|
||||
* @param nbtcompoundSrc Data to merge
|
||||
*/
|
||||
public static void mergeOtherNBTCompound(NBTCompound comp, NBTCompound nbtcompoundSrc) {
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp))
|
||||
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
Object rootnbttagSrc = nbtcompoundSrc.getCompound();
|
||||
if (rootnbttagSrc == null) {
|
||||
rootnbttagSrc = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(nbtcompoundSrc))
|
||||
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
||||
Object workingtagSrc = gettoCompount(rootnbttagSrc, nbtcompoundSrc);
|
||||
try {
|
||||
ReflectionMethod.COMPOUND_MERGE.run(workingtag, workingtagSrc);
|
||||
comp.setCompound(rootnbttag);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while merging two NBTCompounds!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content for a given key inside a Compound
|
||||
*
|
||||
* @param comp
|
||||
* @param key
|
||||
* @return Content saved under this key
|
||||
*/
|
||||
public static String getContent(NBTCompound comp, String key) {
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp))
|
||||
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
try {
|
||||
return ReflectionMethod.COMPOUND_GET.run(workingtag, key).toString();
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while getting the Content for key '" + key + "'!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a key in a {@link NBTCompound} to a given value
|
||||
*
|
||||
* @param comp
|
||||
* @param key
|
||||
* @param val
|
||||
*/
|
||||
public static void set(NBTCompound comp, String key, Object val) {
|
||||
if (val == null) {
|
||||
remove(comp, key);
|
||||
return;
|
||||
}
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp)) {
|
||||
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
||||
}
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
try {
|
||||
ReflectionMethod.COMPOUND_SET.run(workingtag, key, val);
|
||||
comp.setCompound(rootnbttag);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while setting key '" + key + "' to '" + val + "'!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the List saved with a given key.
|
||||
*
|
||||
* @param comp
|
||||
* @param key
|
||||
* @param type
|
||||
* @param clazz
|
||||
* @return The list at that key. Null if it's an invalide type
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> NBTList<T> getList(NBTCompound comp, String key, NBTType type, Class<T> clazz) {
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp))
|
||||
return null;
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
try {
|
||||
Object nbt = ReflectionMethod.COMPOUND_GET_LIST.run(workingtag, key, type.getId());
|
||||
if (clazz == String.class) {
|
||||
return (NBTList<T>) new NBTStringList(comp, key, type, nbt);
|
||||
} else if (clazz == NBTListCompound.class) {
|
||||
return (NBTList<T>) new NBTCompoundList(comp, key, type, nbt);
|
||||
} else if (clazz == Integer.class) {
|
||||
return (NBTList<T>) new NBTIntegerList(comp, key, type, nbt);
|
||||
} else if (clazz == Float.class) {
|
||||
return (NBTList<T>) new NBTFloatList(comp, key, type, nbt);
|
||||
} else if (clazz == Double.class) {
|
||||
return (NBTList<T>) new NBTDoubleList(comp, key, type, nbt);
|
||||
} else if (clazz == Long.class) {
|
||||
return (NBTList<T>) new NBTLongList(comp, key, type, nbt);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Exception while getting a list with the type '" + type + "'!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses Gson to set a {@link Serializable} value in a Compound
|
||||
*
|
||||
* @param comp
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void setObject(NBTCompound comp, String key, Object value) {
|
||||
if (!MinecraftVersion.hasGsonSupport())
|
||||
return;
|
||||
try {
|
||||
String json = GsonWrapper.getString(value);
|
||||
setData(comp, ReflectionMethod.COMPOUND_SET_STRING, key, json);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while setting the Object '" + value + "'!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses Gson to load back a {@link Serializable} object from the Compound
|
||||
*
|
||||
* @param comp
|
||||
* @param key
|
||||
* @param type
|
||||
* @return The loaded Object or null, if not found
|
||||
*/
|
||||
public static <T> T getObject(NBTCompound comp, String key, Class<T> type) {
|
||||
if (!MinecraftVersion.hasGsonSupport())
|
||||
return null;
|
||||
String json = (String) getData(comp, ReflectionMethod.COMPOUND_GET_STRING, key);
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
return GsonWrapper.deserializeJson(json, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the given key
|
||||
*
|
||||
* @param comp
|
||||
* @param key
|
||||
*/
|
||||
public static void remove(NBTCompound comp, String key) {
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp))
|
||||
return;
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
ReflectionMethod.COMPOUND_REMOVE_KEY.run(workingtag, key);
|
||||
comp.setCompound(rootnbttag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Keyset inside this Compound
|
||||
*
|
||||
* @param comp
|
||||
* @return Set of all keys
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Set<String> getKeys(NBTCompound comp) {
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp))
|
||||
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
return (Set<String>) ReflectionMethod.COMPOUND_GET_KEYS.run(workingtag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets data inside the Compound
|
||||
*
|
||||
* @param comp
|
||||
* @param type
|
||||
* @param key
|
||||
* @param data
|
||||
*/
|
||||
public static void setData(NBTCompound comp, ReflectionMethod type, String key, Object data) {
|
||||
if (data == null) {
|
||||
remove(comp, key);
|
||||
return;
|
||||
}
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp))
|
||||
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
type.run(workingtag, key, data);
|
||||
comp.setCompound(rootnbttag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data from the Compound
|
||||
*
|
||||
* @param comp
|
||||
* @param type
|
||||
* @param key
|
||||
* @return The value or default fallback from NMS
|
||||
*/
|
||||
public static Object getData(NBTCompound comp, ReflectionMethod type, String key) {
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
return null;
|
||||
}
|
||||
if (!valideCompound(comp))
|
||||
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
return type.run(workingtag, key);
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* String implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTStringList extends NBTList<String> {
|
||||
|
||||
protected NBTStringList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
super(owner, name, type, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(int index) {
|
||||
try {
|
||||
return (String) ReflectionMethod.LIST_GET_STRING.run(listObject, index);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object asTag(String object) {
|
||||
try {
|
||||
Constructor<?> con = ClassWrapper.NMS_NBTTAGSTRING.getClazz().getDeclaredConstructor(String.class);
|
||||
con.setAccessible(true);
|
||||
return con.newInstance(object);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
||||
| NoSuchMethodException | SecurityException e) {
|
||||
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.annotations.AvaliableSince;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.annotations.CheckUtil;
|
||||
|
||||
/**
|
||||
* NBT class to access vanilla tags from TileEntities. TileEntities don't
|
||||
* support custom tags. Use the NBTInjector for custom tags. Changes will be
|
||||
* instantly applied to the Tile, use the merge method to do many things at
|
||||
* once.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTTileEntity extends NBTCompound {
|
||||
|
||||
private final BlockState tile;
|
||||
|
||||
/**
|
||||
* @param tile BlockState from any TileEntity
|
||||
*/
|
||||
public NBTTileEntity(BlockState tile) {
|
||||
super(null, null);
|
||||
if (tile == null || (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3) && !tile.isPlaced())) {
|
||||
throw new NullPointerException("Tile can't be null/not placed!");
|
||||
}
|
||||
this.tile = tile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return NBTReflectionUtil.getTileEntityNBTTagCompound(tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCompound(Object compound) {
|
||||
NBTReflectionUtil.setTileEntityNBTTagCompound(tile, compound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the NBTCompound used by spigots PersistentDataAPI. This method is only
|
||||
* available for 1.14+!
|
||||
*
|
||||
* @return NBTCompound containing the data of the PersistentDataAPI
|
||||
*/
|
||||
@AvaliableSince(version = MinecraftVersion.MC1_14_R1)
|
||||
public NBTCompound getPersistentDataContainer() {
|
||||
if (hasKey("PublicBukkitValues")) {
|
||||
return getCompound("PublicBukkitValues");
|
||||
} else {
|
||||
NBTContainer container = new NBTContainer();
|
||||
container.addCompound("PublicBukkitValues").setString("__nbtapi",
|
||||
"Marker to make the PersistentDataContainer have content");
|
||||
mergeCompound(container);
|
||||
return getCompound("PublicBukkitValues");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
/**
|
||||
* Enum of all NBT Types Minecraft contains
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum NBTType {
|
||||
NBTTagEnd(0),
|
||||
NBTTagByte(1),
|
||||
NBTTagShort(2),
|
||||
NBTTagInt(3),
|
||||
NBTTagLong(4),
|
||||
NBTTagFloat(5),
|
||||
NBTTagDouble(6),
|
||||
NBTTagByteArray(7),
|
||||
NBTTagIntArray(11),
|
||||
NBTTagString(8),
|
||||
NBTTagList(9),
|
||||
NBTTagCompound(10);
|
||||
|
||||
NBTType(int i) {
|
||||
id = i;
|
||||
}
|
||||
|
||||
private final int id;
|
||||
|
||||
/**
|
||||
* @return Id used by Minecraft internally
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id Internal Minecraft id
|
||||
* @return Enum representing the id, NBTTagEnd for invalide ids
|
||||
*/
|
||||
public static NBTType valueOf(int id) {
|
||||
for (NBTType t : values())
|
||||
if (t.getId() == id)
|
||||
return t;
|
||||
return NBTType.NBTTagEnd;
|
||||
}
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi;
|
||||
|
||||
/**
|
||||
* A generic {@link RuntimeException} that can be thrown by most methods in the
|
||||
* NBTAPI.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NbtApiException extends RuntimeException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -993309714559452334L;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public NbtApiException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
* @param cause
|
||||
* @param enableSuppression
|
||||
* @param writableStackTrace
|
||||
*/
|
||||
public NbtApiException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
* @param cause
|
||||
*/
|
||||
public NbtApiException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
*/
|
||||
public NbtApiException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cause
|
||||
*/
|
||||
public NbtApiException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
@ -1,387 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi.utils;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import static com.songoda.epicenchants.utils.itemnbtapi.utils.MinecraftVersion.logger;
|
||||
|
||||
/**
|
||||
* bStats collects some data for plugin authors.
|
||||
* <p>
|
||||
* Check out https://bStats.org/ to learn more about bStats!
|
||||
*
|
||||
* This class is modified by tr7zw to work when the api is shaded into other peoples plugins.
|
||||
*/
|
||||
public class ApiMetricsLite {
|
||||
|
||||
private static final String PLUGINNAME = "ItemNBTAPI"; // DO NOT CHANGE THE NAME! else it won't link the data on bStats
|
||||
|
||||
// The version of this bStats class
|
||||
public static final int B_STATS_VERSION = 1;
|
||||
|
||||
// The version of the NBT-Api bStats
|
||||
public static final int NBT_BSTATS_VERSION = 1;
|
||||
|
||||
// The url to which the data is sent
|
||||
private static final String URL = "https://bStats.org/submitData/bukkit";
|
||||
|
||||
// Is bStats enabled on this server?
|
||||
private boolean enabled;
|
||||
|
||||
// Should failed requests be logged?
|
||||
private static boolean logFailedRequests;
|
||||
|
||||
// Should the sent data be logged?
|
||||
private static boolean logSentData;
|
||||
|
||||
// Should the response text be logged?
|
||||
private static boolean logResponseStatusText;
|
||||
|
||||
// The uuid of the server
|
||||
private static String serverUUID;
|
||||
|
||||
// The plugin
|
||||
private Plugin plugin;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
*/
|
||||
public ApiMetricsLite() {
|
||||
|
||||
// The register method just uses any enabled plugin it can find to register. This *shouldn't* cause any problems, since the plugin isn't used any other way.
|
||||
// Register our service
|
||||
for(Plugin plug : Bukkit.getPluginManager().getPlugins()) {
|
||||
plugin = plug;
|
||||
if(plugin != null)
|
||||
break;
|
||||
}
|
||||
if(plugin == null) {
|
||||
return;// Didn't find any plugin that could work
|
||||
}
|
||||
|
||||
// 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);
|
||||
// Should the sent data be logged?
|
||||
config.addDefault("logSentData", false);
|
||||
// Should the response text be logged?
|
||||
config.addDefault("logResponseStatusText", 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);
|
||||
enabled = config.getBoolean("enabled", true);
|
||||
logSentData = config.getBoolean("logSentData", false);
|
||||
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||
if (enabled) {
|
||||
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("NBT_BSTATS_VERSION"); // Create only one instance of the nbt-api bstats.
|
||||
return;
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
found = true; // We aren't the first
|
||||
break;
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
boolean fFound = found;
|
||||
// Register our service
|
||||
if(Bukkit.isPrimaryThread()){
|
||||
Bukkit.getServicesManager().register(ApiMetricsLite.class, this, plugin, ServicePriority.Normal);
|
||||
if (!fFound) {
|
||||
logger.info("[NBTAPI] Using the plugin '" + plugin.getName() + "' to create a bStats instance!");
|
||||
// We are the first!
|
||||
startSubmitting();
|
||||
}
|
||||
}else{
|
||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
||||
Bukkit.getServicesManager().register(ApiMetricsLite.class, this, plugin, ServicePriority.Normal);
|
||||
if (!fFound) {
|
||||
logger.info("[NBTAPI] Using the plugin '" + plugin.getName() + "' to create a bStats instance!");
|
||||
// We are the first!
|
||||
startSubmitting();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if bStats is enabled.
|
||||
*
|
||||
* @return Whether bStats is enabled or not.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, () -> submitData());
|
||||
}
|
||||
}, 1000l * 60l * 5l, 1000l * 60l * 30l);
|
||||
// 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.
|
||||
*/
|
||||
public JsonObject getPluginData() {
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
data.addProperty("pluginName", PLUGINNAME); // Append the name of the plugin
|
||||
data.addProperty("pluginVersion", MinecraftVersion.VERSION); // Append the version of the plugin
|
||||
data.add("customCharts", new JsonArray());
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server specific data.
|
||||
*
|
||||
* @return The server specific data.
|
||||
*/
|
||||
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 = Bukkit.getVersion();
|
||||
String bukkitName = Bukkit.getName();
|
||||
|
||||
// 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.addProperty("serverUUID", serverUUID);
|
||||
|
||||
data.addProperty("playerAmount", playerAmount);
|
||||
data.addProperty("onlineMode", onlineMode);
|
||||
data.addProperty("bukkitVersion", bukkitVersion);
|
||||
data.addProperty("bukkitName", bukkitName);
|
||||
|
||||
data.addProperty("javaVersion", javaVersion);
|
||||
data.addProperty("osName", osName);
|
||||
data.addProperty("osArch", osArch);
|
||||
data.addProperty("osVersion", osVersion);
|
||||
data.addProperty("coreCount", coreCount);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the data and sends it afterwards.
|
||||
*/
|
||||
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 {
|
||||
Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider());
|
||||
if (plugin instanceof JsonObject) {
|
||||
pluginData.add((JsonObject) plugin);
|
||||
} else { // old bstats version compatibility
|
||||
try {
|
||||
Class<?> jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject");
|
||||
if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) {
|
||||
Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString");
|
||||
jsonStringGetter.setAccessible(true);
|
||||
String jsonString = (String) jsonStringGetter.invoke(plugin);
|
||||
JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject();
|
||||
pluginData.add(object);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
// minecraft version 1.14+
|
||||
if (logFailedRequests) {
|
||||
logger.log(Level.WARNING, "[NBTAPI][BSTATS] Encountered exception while posting request!", e);
|
||||
// Not using the plugins logger since the plugin isn't the plugin containing the NBT-Api most of the time
|
||||
//this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception ", e);
|
||||
}
|
||||
continue; // continue looping since we cannot do any other thing.
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {
|
||||
}
|
||||
}
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
|
||||
data.add("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(plugin, data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logFailedRequests) {
|
||||
logger.log(Level.WARNING, "[NBTAPI][BSTATS] Could not submit plugin stats of " + plugin.getName(), e);
|
||||
// Not using the plugins logger since the plugin isn't the plugin containing the NBT-Api most of the time
|
||||
//plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the data to the bStats server.
|
||||
*
|
||||
* @param plugin Any plugin. It's just used to get a logger instance.
|
||||
* @param data The data to send.
|
||||
* @throws Exception If the request failed.
|
||||
*/
|
||||
private static void sendData(Plugin plugin, 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!");
|
||||
}
|
||||
if (logSentData) {
|
||||
System.out.println("[NBTAPI][BSTATS] Sending data to bStats: " + data.toString());
|
||||
// Not using the plugins logger since the plugin isn't the plugin containing the NBT-Api most of the time
|
||||
//plugin.getLogger().info("Sending data to bStats: " + data.toString());
|
||||
}
|
||||
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();
|
||||
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
bufferedReader.close();
|
||||
if (logResponseStatusText) {
|
||||
logger.info("[NBTAPI][BSTATS] Sent data to bStats and received response: " + builder.toString());
|
||||
// Not using the plugins logger since the plugin isn't the plugin containing the NBT-Api most of the time
|
||||
//plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 new byte[0];
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
||||
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
||||
gzip.close();
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi.utils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NbtApiException;
|
||||
|
||||
/**
|
||||
* Helper class for 1.7 servers without Gson
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class GsonWrapper {
|
||||
|
||||
/**
|
||||
* Private constructor
|
||||
*/
|
||||
private GsonWrapper() {
|
||||
|
||||
}
|
||||
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
/**
|
||||
* Turns Objects into Json Strings
|
||||
*
|
||||
* @param obj
|
||||
* @return Json, representing the Object
|
||||
*/
|
||||
public static String getString(Object obj) {
|
||||
return gson.toJson(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an Object of the given type using the Json String
|
||||
*
|
||||
* @param json
|
||||
* @param type
|
||||
* @return Object that got created, or null if the json is null
|
||||
*/
|
||||
public static <T> T deserializeJson(String json, Class<T> type) {
|
||||
try {
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
T obj = gson.fromJson(json, type);
|
||||
return type.cast(obj);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Error while converting json to " + type.getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi.utils;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
/**
|
||||
* This class acts as the "Brain" of the NBTApi. It contains the main logger for
|
||||
* other classes,registers bStats and checks rather Maven shading was done
|
||||
* correctly.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum MinecraftVersion {
|
||||
UNKNOWN(Integer.MAX_VALUE), // Use the newest known mappings
|
||||
MC1_7_R4(174), MC1_8_R3(183), MC1_9_R1(191), MC1_9_R2(192), MC1_10_R1(1101), MC1_11_R1(1111), MC1_12_R1(1121),
|
||||
MC1_13_R1(1131), MC1_13_R2(1132), MC1_14_R1(1141), MC1_15_R1(1151), MC1_16_R1(1161);
|
||||
|
||||
private static MinecraftVersion version;
|
||||
private static Boolean hasGsonSupport;
|
||||
private static boolean bStatsDisabled = false;
|
||||
private static boolean disablePackageWarning = false;
|
||||
private static boolean updateCheckDisabled = false;
|
||||
/**
|
||||
* Logger used by the api
|
||||
*/
|
||||
public static final Logger logger = Logger.getLogger("NBTAPI");
|
||||
|
||||
// NBT-API Version
|
||||
protected static final String VERSION = "2.5.0-SNAPSHOT";
|
||||
|
||||
private final int versionId;
|
||||
|
||||
MinecraftVersion(int versionId) {
|
||||
this.versionId = versionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A simple comparable Integer, representing the version.
|
||||
*/
|
||||
public int getVersionId() {
|
||||
return versionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current versions is at least the given Version
|
||||
*
|
||||
* @param version The minimum version
|
||||
* @return
|
||||
*/
|
||||
public static boolean isAtLeastVersion(MinecraftVersion version) {
|
||||
return getVersion().getVersionId() >= version.getVersionId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for this servers MinecraftVersion. Also init's bStats and checks the
|
||||
* shading.
|
||||
*
|
||||
* @return The enum for the MinecraftVersion this server is running
|
||||
*/
|
||||
public static MinecraftVersion getVersion() {
|
||||
if (version != null) {
|
||||
return version;
|
||||
}
|
||||
final String ver = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||
logger.info("[NBTAPI] Found Spigot: " + ver + "! Trying to find NMS support");
|
||||
try {
|
||||
version = MinecraftVersion.valueOf(ver.replace("v", "MC"));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
version = MinecraftVersion.UNKNOWN;
|
||||
}
|
||||
if (version != UNKNOWN) {
|
||||
logger.info("[NBTAPI] NMS support '" + version.name() + "' loaded!");
|
||||
} else {
|
||||
logger.warning("[NBTAPI] Wasn't able to find NMS Support! Some functions may not work!");
|
||||
}
|
||||
init();
|
||||
return version;
|
||||
}
|
||||
|
||||
private static void init() {
|
||||
try {
|
||||
if (hasGsonSupport() && !bStatsDisabled)
|
||||
new ApiMetricsLite();
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "[NBTAPI] Error enabling Metrics!", ex);
|
||||
}
|
||||
|
||||
if (hasGsonSupport() && !updateCheckDisabled)
|
||||
new Thread(() -> {
|
||||
try {
|
||||
VersionChecker.checkForUpdates();
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "[NBTAPI] Error while checking for updates!", ex);
|
||||
}
|
||||
}).start();
|
||||
// Maven's Relocate is clever and changes strings, too. So we have to use this
|
||||
// little "trick" ... :D (from bStats)
|
||||
final String defaultPackage = new String(new byte[] { 'd', 'e', '.', 't', 'r', '7', 'z', 'w', '.', 'c', 'h',
|
||||
'a', 'n', 'g', 'e', 'm', 'e', '.', 'n', 'b', 't', 'a', 'p', 'i', '.', 'u', 't', 'i', 'l', 's' });
|
||||
if (!disablePackageWarning && MinecraftVersion.class.getPackage().getName().equals(defaultPackage)) {
|
||||
logger.warning(
|
||||
"#########################################- NBTAPI -#########################################");
|
||||
logger.warning(
|
||||
"The NBT-API package has not been moved! This *will* cause problems with other plugins containing");
|
||||
logger.warning(
|
||||
"a different version of the api! Please read the guide on the plugin page on how to get the");
|
||||
logger.warning(
|
||||
"Maven Shade plugin to relocate the api to your personal location! If you are not the developer,");
|
||||
logger.warning("please check your plugins and contact their developer, so he can fix this issue.");
|
||||
logger.warning(
|
||||
"#########################################- NBTAPI -#########################################");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True, if Gson is usable
|
||||
*/
|
||||
public static boolean hasGsonSupport() {
|
||||
if (hasGsonSupport != null) {
|
||||
return hasGsonSupport;
|
||||
}
|
||||
try {
|
||||
logger.info("[NBTAPI] Found Gson: " + Class.forName("com.google.gson.Gson"));
|
||||
hasGsonSupport = true;
|
||||
} catch (Exception ex) {
|
||||
logger.info("[NBTAPI] Gson not found! This will not allow the usage of some methods!");
|
||||
hasGsonSupport = false;
|
||||
}
|
||||
return hasGsonSupport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calling this function before the NBT-Api is used will disable bStats stats
|
||||
* collection. Please consider not to do that, since it won't affect your plugin
|
||||
* and helps the NBT-Api developer to see api's demand.
|
||||
*/
|
||||
public static void disableBStats() {
|
||||
bStatsDisabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the update check. Uses Spiget to get the current version and prints
|
||||
* a warning when outdated.
|
||||
*/
|
||||
public static void disableUpdateCheck() {
|
||||
updateCheckDisabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forcefully disables the log message for plugins not shading the API to
|
||||
* another location. This may be helpful for networks or development
|
||||
* environments, but please don't use it for plugins that are uploaded to
|
||||
* Spigotmc.
|
||||
*/
|
||||
public static void disablePackageWarning() {
|
||||
disablePackageWarning = true;
|
||||
}
|
||||
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi.utils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NbtApiException;
|
||||
|
||||
public final class ReflectionUtil {
|
||||
|
||||
private static Field field_modifiers;
|
||||
|
||||
static {
|
||||
try {
|
||||
field_modifiers = Field.class.getDeclaredField("modifiers");
|
||||
field_modifiers.setAccessible(true);
|
||||
} catch (NoSuchFieldException ex) {
|
||||
try {
|
||||
// This hacky workaround is for newer jdk versions 11+?
|
||||
Method fieldGetter = Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class);
|
||||
fieldGetter.setAccessible(true);
|
||||
Field[] fields = (Field[]) fieldGetter.invoke(Field.class, false);
|
||||
for (Field f : fields)
|
||||
if (f.getName().equals("modifiers")) {
|
||||
field_modifiers = f;
|
||||
field_modifiers.setAccessible(true);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException(e);
|
||||
}
|
||||
}
|
||||
if (field_modifiers == null) {
|
||||
throw new NbtApiException("Unable to init the modifiers Field.");
|
||||
}
|
||||
}
|
||||
|
||||
public static Field makeNonFinal(Field field) throws IllegalArgumentException, IllegalAccessException {
|
||||
int mods = field.getModifiers();
|
||||
if (Modifier.isFinal(mods)) {
|
||||
field_modifiers.set(field, mods & ~Modifier.FINAL);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
public static void setFinal(Object obj, Field field, Object newValue)
|
||||
throws IllegalArgumentException, IllegalAccessException {
|
||||
field.setAccessible(true);
|
||||
field = makeNonFinal(field);
|
||||
field.set(obj, newValue);
|
||||
}
|
||||
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi.utils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
|
||||
/**
|
||||
* This class uses the Spiget API to check for updates
|
||||
*
|
||||
*/
|
||||
public class VersionChecker {
|
||||
|
||||
private static final String USER_AGENT = "nbt-api Version check";
|
||||
private static final String REQUEST_URL = "https://api.spiget.org/v2/resources/7939/versions?size=100";
|
||||
|
||||
protected static void checkForUpdates() throws Exception {
|
||||
URL url = new URL(REQUEST_URL);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.addRequestProperty("User-Agent", USER_AGENT);// Set
|
||||
// User-Agent
|
||||
|
||||
// If you're not sure if the request will be successful,
|
||||
// you need to check the response code and use #getErrorStream if it
|
||||
// returned an error code
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
InputStreamReader reader = new InputStreamReader(inputStream);
|
||||
|
||||
// This could be either a JsonArray or JsonObject
|
||||
JsonElement element = new JsonParser().parse(reader);
|
||||
if (element.isJsonArray()) {
|
||||
// Is JsonArray
|
||||
JsonArray updates = (JsonArray) element;
|
||||
JsonObject latest = (JsonObject) updates.get(updates.size() - 1);
|
||||
int versionDifference = getVersionDifference(latest.get("name").getAsString());
|
||||
if (versionDifference == -1) { // Outdated
|
||||
MinecraftVersion.logger.log(Level.WARNING,
|
||||
"[NBTAPI] The NBT-API at '" + NBTItem.class.getPackage() + "' seems to be outdated!");
|
||||
MinecraftVersion.logger.log(Level.WARNING, "[NBTAPI] Current Version: '" + MinecraftVersion.VERSION
|
||||
+ "' Newest Version: " + latest.get("name").getAsString() + "'");
|
||||
MinecraftVersion.logger.log(Level.WARNING,
|
||||
"[NBTAPI] Please update the nbt-api or the plugin that contains the api!");
|
||||
|
||||
} else if (versionDifference == 0) {
|
||||
MinecraftVersion.logger.log(Level.INFO, "[NBTAPI] The NBT-API seems to be up-to-date!");
|
||||
} else if (versionDifference == 1) {
|
||||
MinecraftVersion.logger.log(Level.WARNING, "[NBTAPI] The NBT-API at '" + NBTItem.class.getPackage()
|
||||
+ "' seems to be a future Version, not yet released on Spigot!");
|
||||
MinecraftVersion.logger.log(Level.WARNING, "[NBTAPI] Current Version: '" + MinecraftVersion.VERSION
|
||||
+ "' Newest Version: " + latest.get("name").getAsString() + "'");
|
||||
}
|
||||
} else {
|
||||
// wut?!
|
||||
MinecraftVersion.logger.log(Level.WARNING,
|
||||
"[NBTAPI] Error when looking for Updates! Got non Json Array: '" + element.toString() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
// -1 = we are outdated
|
||||
// 0 = up to date
|
||||
// 1 = using a future version
|
||||
// This method is only able to compare the Format 0.0.0(-SNAPSHOT)
|
||||
private static int getVersionDifference(String version) {
|
||||
String current = MinecraftVersion.VERSION;
|
||||
if (current.equals(version))
|
||||
return 0;
|
||||
String pattern = "\\.";
|
||||
if (current.split(pattern).length != 3 || version.split(pattern).length != 3)
|
||||
return -1;
|
||||
int curMaj = Integer.parseInt(current.split(pattern)[0]);
|
||||
int curMin = Integer.parseInt(current.split(pattern)[1]);
|
||||
String curPatch = current.split(pattern)[2];
|
||||
int relMaj = Integer.parseInt(version.split(pattern)[0]);
|
||||
int relMin = Integer.parseInt(version.split(pattern)[1]);
|
||||
String relPatch = version.split(pattern)[2];
|
||||
if (curMaj < relMaj)
|
||||
return -1;
|
||||
if (curMaj > relMaj)
|
||||
return 1;
|
||||
if (curMin < relMin)
|
||||
return -1;
|
||||
if (curMin > relMin)
|
||||
return 1;
|
||||
int curPatchN = Integer.parseInt(curPatch.split("-")[0]);
|
||||
int relPatchN = Integer.parseInt(relPatch.split("-")[0]);
|
||||
if (curPatchN < relPatchN)
|
||||
return -1;
|
||||
if (curPatchN > relPatchN)
|
||||
return 1;
|
||||
if (!relPatch.contains("-") && curPatch.contains("-"))
|
||||
return -1; // Release has no - but we do = We use a Snapshot of the
|
||||
// release
|
||||
if (relPatch.contains("-") && curPatch.contains("-"))
|
||||
return 0; // Release and cur are Snapshots/alpha/beta
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi.utils.annotations;
|
||||
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
|
||||
@Retention(RUNTIME)
|
||||
@Target({ METHOD })
|
||||
public @interface AvaliableSince {
|
||||
|
||||
MinecraftVersion version();
|
||||
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi.utils.annotations;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NbtApiException;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
|
||||
public class CheckUtil {
|
||||
|
||||
public static boolean isAvaliable(Method method) {
|
||||
if(MinecraftVersion.getVersion().getVersionId() < method.getAnnotation(AvaliableSince.class).version().getVersionId())
|
||||
throw new NbtApiException("The Method '" + method.getName() + "' is only avaliable for the Versions " + method.getAnnotation(AvaliableSince.class).version() + "+, but still got called!");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
import static com.songoda.epicenchants.utils.itemnbtapi.utils.MinecraftVersion.logger;
|
||||
|
||||
/**
|
||||
* Wraps NMS and CRAFT classes
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum ClassWrapper {
|
||||
CRAFT_ITEMSTACK(PackageWrapper.CRAFTBUKKIT, "inventory.CraftItemStack"),
|
||||
CRAFT_METAITEM(PackageWrapper.CRAFTBUKKIT, "inventory.CraftMetaItem"),
|
||||
CRAFT_ENTITY(PackageWrapper.CRAFTBUKKIT, "entity.CraftEntity"),
|
||||
CRAFT_WORLD(PackageWrapper.CRAFTBUKKIT, "CraftWorld"),
|
||||
NMS_NBTBASE(PackageWrapper.NMS, "NBTBase"),
|
||||
NMS_NBTTAGSTRING(PackageWrapper.NMS, "NBTTagString"),
|
||||
NMS_NBTTAGINT(PackageWrapper.NMS, "NBTTagInt"),
|
||||
NMS_NBTTAGFLOAT(PackageWrapper.NMS, "NBTTagFloat"),
|
||||
NMS_NBTTAGDOUBLE(PackageWrapper.NMS, "NBTTagDouble"),
|
||||
NMS_NBTTAGLONG(PackageWrapper.NMS, "NBTTagLong"),
|
||||
NMS_ITEMSTACK(PackageWrapper.NMS, "ItemStack"),
|
||||
NMS_NBTTAGCOMPOUND(PackageWrapper.NMS, "NBTTagCompound"),
|
||||
NMS_NBTTAGLIST(PackageWrapper.NMS, "NBTTagList"),
|
||||
NMS_NBTCOMPRESSEDSTREAMTOOLS(PackageWrapper.NMS, "NBTCompressedStreamTools"),
|
||||
NMS_MOJANGSONPARSER(PackageWrapper.NMS, "MojangsonParser"),
|
||||
NMS_TILEENTITY(PackageWrapper.NMS, "TileEntity"),
|
||||
NMS_BLOCKPOSITION(PackageWrapper.NMS, "BlockPosition", MinecraftVersion.MC1_8_R3, null),
|
||||
NMS_WORLDSERVER(PackageWrapper.NMS, "WorldServer"),
|
||||
NMS_MINECRAFTSERVER(PackageWrapper.NMS, "MinecraftServer"),
|
||||
NMS_WORLD(PackageWrapper.NMS, "World"),
|
||||
NMS_ENTITY(PackageWrapper.NMS, "Entity"),
|
||||
NMS_ENTITYTYPES(PackageWrapper.NMS, "EntityTypes"),
|
||||
NMS_REGISTRYSIMPLE(PackageWrapper.NMS, "RegistrySimple", MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_12_R1),
|
||||
NMS_REGISTRYMATERIALS(PackageWrapper.NMS, "RegistryMaterials"),
|
||||
NMS_IREGISTRY(PackageWrapper.NMS, "IRegistry"),
|
||||
NMS_MINECRAFTKEY(PackageWrapper.NMS, "MinecraftKey", MinecraftVersion.MC1_8_R3, null),
|
||||
NMS_GAMEPROFILESERIALIZER(PackageWrapper.NMS, "GameProfileSerializer"),
|
||||
NMS_IBLOCKDATA(PackageWrapper.NMS, "IBlockData", MinecraftVersion.MC1_8_R3, null),
|
||||
GAMEPROFILE("com.mojang.authlib.GameProfile", MinecraftVersion.MC1_8_R3)
|
||||
;
|
||||
|
||||
private Class<?> clazz;
|
||||
private boolean enabled = false;
|
||||
|
||||
ClassWrapper(PackageWrapper packageId, String suffix){
|
||||
this(packageId, suffix, null, null);
|
||||
}
|
||||
|
||||
ClassWrapper(PackageWrapper packageId, String suffix, MinecraftVersion from, MinecraftVersion to){
|
||||
if(from != null && MinecraftVersion.getVersion().getVersionId() < from.getVersionId()) {
|
||||
return;
|
||||
}
|
||||
if(to != null && MinecraftVersion.getVersion().getVersionId() > to.getVersionId()) {
|
||||
return;
|
||||
}
|
||||
enabled = true;
|
||||
try{
|
||||
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
clazz = Class.forName(packageId.getUri() + "." + version + "." + suffix);
|
||||
}catch(Exception ex){
|
||||
logger.log(Level.WARNING, "[NBTAPI] Error while trying to resolve the class '" + suffix + "'!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
ClassWrapper(String path, MinecraftVersion from){
|
||||
if(from != null && MinecraftVersion.getVersion().getVersionId() < from.getVersionId()) {
|
||||
return;
|
||||
}
|
||||
enabled = true;
|
||||
try{
|
||||
clazz = Class.forName(path);
|
||||
}catch(Exception ex){
|
||||
logger.log(Level.WARNING, "[NBTAPI] Error while trying to resolve the class '" + path + "'!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The wrapped class
|
||||
*/
|
||||
public Class<?> getClazz(){
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Is this class available in this Version
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NbtApiException;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
|
||||
import static com.songoda.epicenchants.utils.itemnbtapi.utils.MinecraftVersion.logger;
|
||||
|
||||
/**
|
||||
* This Enum wraps Constructors for NMS classes
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum ObjectCreator {
|
||||
NMS_NBTTAGCOMPOUND(null, null, ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()),
|
||||
NMS_BLOCKPOSITION(null, null, ClassWrapper.NMS_BLOCKPOSITION.getClazz(), int.class, int.class, int.class),
|
||||
NMS_COMPOUNDFROMITEM(MinecraftVersion.MC1_11_R1, null, ClassWrapper.NMS_ITEMSTACK.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()),;
|
||||
|
||||
private Constructor<?> construct;
|
||||
private Class<?> targetClass;
|
||||
|
||||
ObjectCreator(MinecraftVersion from, MinecraftVersion to, Class<?> clazz, Class<?>... args) {
|
||||
if (clazz == null)
|
||||
return;
|
||||
if (from != null && MinecraftVersion.getVersion().getVersionId() < from.getVersionId())
|
||||
return;
|
||||
if (to != null && MinecraftVersion.getVersion().getVersionId() > to.getVersionId())
|
||||
return;
|
||||
try {
|
||||
this.targetClass = clazz;
|
||||
construct = clazz.getDeclaredConstructor(args);
|
||||
construct.setAccessible(true);
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Unable to find the constructor for the class '" + clazz.getName() + "'", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an Object instance with given args
|
||||
*
|
||||
* @param args
|
||||
* @return Object created
|
||||
*/
|
||||
public Object getInstance(Object... args) {
|
||||
try {
|
||||
return construct.newInstance(args);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Exception while creating a new instance of '" + targetClass + "'", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings;
|
||||
|
||||
/**
|
||||
* Package enum
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum PackageWrapper {
|
||||
NMS(new String(new byte[] {'n', 'e', 't', '.', 'm', 'i', 'n', 'e', 'c', 'r', 'a', 'f', 't', '.', 's', 'e', 'r', 'v', 'e', 'r'})),
|
||||
CRAFTBUKKIT(new String(new byte[] {'o', 'r', 'g', '.', 'b', 'u', 'k', 'k', 'i', 't', '.', 'c', 'r', 'a', 'f', 't', 'b', 'u', 'k', 'k', 'i', 't'})),
|
||||
;
|
||||
|
||||
private final String uri;
|
||||
|
||||
private PackageWrapper(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Uri for that package
|
||||
*/
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
}
|
@ -1,192 +0,0 @@
|
||||
package com.songoda.epicenchants.utils.itemnbtapi.utils.nmsmappings;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NbtApiException;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
|
||||
/**
|
||||
* This class caches method reflections, keeps track of method name changes between versions and allows early checking for problems
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum ReflectionMethod {
|
||||
|
||||
COMPOUND_SET_FLOAT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, float.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setFloat")),
|
||||
COMPOUND_SET_STRING(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setString")),
|
||||
COMPOUND_SET_INT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setInt")),
|
||||
COMPOUND_SET_BYTEARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, byte[].class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setByteArray")),
|
||||
COMPOUND_SET_INTARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, int[].class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setIntArray")),
|
||||
COMPOUND_SET_LONG(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, long.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setLong")),
|
||||
COMPOUND_SET_SHORT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, short.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setShort")),
|
||||
COMPOUND_SET_BYTE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, byte.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setByte")),
|
||||
COMPOUND_SET_DOUBLE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, double.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setDouble")),
|
||||
COMPOUND_SET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, boolean.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setBoolean")),
|
||||
COMPOUND_SET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, UUID.class}, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "a")),
|
||||
COMPOUND_MERGE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a")), //FIXME: No Spigot mapping!
|
||||
COMPOUND_SET(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "set")),
|
||||
COMPOUND_GET(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get")),
|
||||
COMPOUND_GET_LIST(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getList")),
|
||||
COMPOUND_OWN_TYPE(ClassWrapper.NMS_NBTBASE.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTypeId")), // Only needed for 1.7.10 getType
|
||||
|
||||
COMPOUND_GET_FLOAT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getFloat")),
|
||||
COMPOUND_GET_STRING(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getString")),
|
||||
COMPOUND_GET_INT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getInt")),
|
||||
COMPOUND_GET_BYTEARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getByteArray")),
|
||||
COMPOUND_GET_INTARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getIntArray")),
|
||||
COMPOUND_GET_LONG(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getLong")),
|
||||
COMPOUND_GET_SHORT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getShort")),
|
||||
COMPOUND_GET_BYTE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getByte")),
|
||||
COMPOUND_GET_DOUBLE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getDouble")),
|
||||
COMPOUND_GET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getBoolean")),
|
||||
COMPOUND_GET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "a")),
|
||||
COMPOUND_GET_COMPOUND(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getCompound")),
|
||||
|
||||
NMSITEM_GETTAG(ClassWrapper.NMS_ITEMSTACK.getClazz(), new Class[] {}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTag")),
|
||||
NMSITEM_SAVE(ClassWrapper.NMS_ITEMSTACK.getClazz(), new Class[] {ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "save")),
|
||||
NMSITEM_CREATESTACK(ClassWrapper.NMS_ITEMSTACK.getClazz(), new Class[] {ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_10_R1, new Since(MinecraftVersion.MC1_7_R4, "createStack")),
|
||||
|
||||
COMPOUND_REMOVE_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "remove")),
|
||||
COMPOUND_HAS_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "hasKey")),
|
||||
COMPOUND_GET_TYPE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "b"), new Since(MinecraftVersion.MC1_9_R1, "d"), new Since(MinecraftVersion.MC1_15_R1, "e"), new Since(MinecraftVersion.MC1_16_R1, "d")), //FIXME: No Spigot mapping!
|
||||
COMPOUND_GET_KEYS(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "c"), new Since(MinecraftVersion.MC1_13_R1, "getKeys")),
|
||||
|
||||
LISTCOMPOUND_GET_KEYS(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "c"), new Since(MinecraftVersion.MC1_13_R1, "getKeys")),
|
||||
LIST_REMOVE_KEY(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"), new Since(MinecraftVersion.MC1_9_R1, "remove")),
|
||||
LIST_SIZE(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "size")),
|
||||
LIST_SET(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class, ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"), new Since(MinecraftVersion.MC1_13_R1, "set")),
|
||||
LEGACY_LIST_ADD(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_13_R2, new Since(MinecraftVersion.MC1_7_R4, "add")),
|
||||
LIST_ADD(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class, ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "add")),
|
||||
LIST_GET_STRING(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getString")),
|
||||
LIST_GET_COMPOUND(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get")),
|
||||
LIST_GET(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get"), new Since(MinecraftVersion.MC1_8_R3, "g"), new Since(MinecraftVersion.MC1_9_R1, "h"), new Since(MinecraftVersion.MC1_12_R1, "i"), new Since(MinecraftVersion.MC1_13_R1, "get")),
|
||||
|
||||
ITEMSTACK_SET_TAG(ClassWrapper.NMS_ITEMSTACK.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setTag")),
|
||||
ITEMSTACK_NMSCOPY(ClassWrapper.CRAFT_ITEMSTACK.getClazz(), new Class[]{ItemStack.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "asNMSCopy")),
|
||||
ITEMSTACK_BUKKITMIRROR(ClassWrapper.CRAFT_ITEMSTACK.getClazz(), new Class[]{ClassWrapper.NMS_ITEMSTACK.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "asCraftMirror")),
|
||||
|
||||
CRAFT_WORLD_GET_HANDLE(ClassWrapper.CRAFT_WORLD.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getHandle")),
|
||||
NMS_WORLD_GET_TILEENTITY(ClassWrapper.NMS_WORLDSERVER.getClazz(), new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "getTileEntity")),
|
||||
NMS_WORLD_SET_TILEENTITY(ClassWrapper.NMS_WORLDSERVER.getClazz(), new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz(), ClassWrapper.NMS_TILEENTITY.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "setTileEntity")),
|
||||
NMS_WORLD_REMOVE_TILEENTITY(ClassWrapper.NMS_WORLDSERVER.getClazz(), new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "t"), new Since(MinecraftVersion.MC1_9_R1, "s"), new Since(MinecraftVersion.MC1_13_R1, "n"), new Since(MinecraftVersion.MC1_14_R1, "removeTileEntity")),
|
||||
|
||||
NMS_WORLD_GET_TILEENTITY_1_7_10(ClassWrapper.NMS_WORLDSERVER.getClazz(), new Class[]{int.class, int.class, int.class}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTileEntity")),
|
||||
|
||||
TILEENTITY_LOAD_LEGACY191(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_MINECRAFTSERVER.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_9_R1, MinecraftVersion.MC1_9_R1, new Since(MinecraftVersion.MC1_9_R1, "a")), //FIXME: No Spigot mapping!
|
||||
TILEENTITY_LOAD_LEGACY183(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, MinecraftVersion.MC1_9_R2, new Since(MinecraftVersion.MC1_8_R3, "c"), new Since(MinecraftVersion.MC1_9_R1, "a"), new Since(MinecraftVersion.MC1_9_R2, "c")), //FIXME: No Spigot mapping!
|
||||
TILEENTITY_LOAD_LEGACY1121(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_WORLD.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_10_R1, MinecraftVersion.MC1_12_R1, new Since(MinecraftVersion.MC1_10_R1, "a"), new Since(MinecraftVersion.MC1_12_R1, "create")),
|
||||
TILEENTITY_LOAD_LEGACY1151(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_13_R1, MinecraftVersion.MC1_15_R1, new Since(MinecraftVersion.MC1_12_R1, "create")),
|
||||
TILEENTITY_LOAD(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_IBLOCKDATA.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "create")),
|
||||
|
||||
TILEENTITY_GET_NBT(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "b"), new Since(MinecraftVersion.MC1_9_R1, "save")),
|
||||
TILEENTITY_SET_NBT_LEGACY1151(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_15_R1, new Since(MinecraftVersion.MC1_7_R4, "a"), new Since(MinecraftVersion.MC1_12_R1, "load")),
|
||||
TILEENTITY_SET_NBT(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_IBLOCKDATA.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "load")),
|
||||
TILEENTITY_GET_BLOCKDATA(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{}, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "getBlock")),
|
||||
|
||||
CRAFT_ENTITY_GET_HANDLE(ClassWrapper.CRAFT_ENTITY.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getHandle")),
|
||||
NMS_ENTITY_SET_NBT(ClassWrapper.NMS_ENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "f"), new Since(MinecraftVersion.MC1_16_R1, "load")), //FIXME: No Spigot mapping!
|
||||
NMS_ENTITY_GET_NBT(ClassWrapper.NMS_ENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "e"), new Since(MinecraftVersion.MC1_12_R1, "save")),
|
||||
NMS_ENTITY_GETSAVEID(ClassWrapper.NMS_ENTITY.getClazz(), new Class[]{}, MinecraftVersion.MC1_14_R1,new Since(MinecraftVersion.MC1_14_R1, "getSaveID")),
|
||||
|
||||
NBTFILE_READ(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS.getClazz(), new Class[]{InputStream.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "a")), //FIXME: No Spigot mapping!
|
||||
NBTFILE_WRITE(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), OutputStream.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "a")), //FIXME: No Spigot mapping!
|
||||
|
||||
PARSE_NBT(ClassWrapper.NMS_MOJANGSONPARSER.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "parse")),
|
||||
REGISTRY_KEYSET (ClassWrapper.NMS_REGISTRYSIMPLE.getClazz(), new Class[]{}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "keySet")),
|
||||
REGISTRY_GET (ClassWrapper.NMS_REGISTRYSIMPLE.getClazz(), new Class[]{Object.class}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "get")),
|
||||
REGISTRY_SET (ClassWrapper.NMS_REGISTRYSIMPLE.getClazz(), new Class[]{Object.class, Object.class}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "a")), //FIXME: No Spigot mapping!
|
||||
REGISTRY_GET_INVERSE (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{Object.class}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "b")), //FIXME: No Spigot mapping!
|
||||
REGISTRYMATERIALS_KEYSET (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{}, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_13_R1, "keySet")),
|
||||
REGISTRYMATERIALS_GET (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{ClassWrapper.NMS_MINECRAFTKEY.getClazz()}, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_13_R1, "get")),
|
||||
REGISTRYMATERIALS_GETKEY (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{Object.class}, MinecraftVersion.MC1_13_R2, new Since(MinecraftVersion.MC1_13_R2, "getKey")),
|
||||
|
||||
GAMEPROFILE_DESERIALIZE (ClassWrapper.NMS_GAMEPROFILESERIALIZER.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "deserialize")),
|
||||
GAMEPROFILE_SERIALIZE (ClassWrapper.NMS_GAMEPROFILESERIALIZER.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), ClassWrapper.GAMEPROFILE.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "serialize"));
|
||||
|
||||
private MinecraftVersion removedAfter;
|
||||
private Since targetVersion;
|
||||
private Method method;
|
||||
private boolean loaded = false;
|
||||
private boolean compatible = false;
|
||||
private String methodName = null;
|
||||
|
||||
ReflectionMethod(Class<?> targetClass, Class<?>[] args, MinecraftVersion addedSince, MinecraftVersion removedAfter, Since... methodnames){
|
||||
this.removedAfter = removedAfter;
|
||||
MinecraftVersion server = MinecraftVersion.getVersion();
|
||||
if(server.compareTo(addedSince) < 0 || (this.removedAfter != null && server.getVersionId() > this.removedAfter.getVersionId()))return;
|
||||
compatible = true;
|
||||
Since target = methodnames[0];
|
||||
for(Since s : methodnames){
|
||||
if(s.version.getVersionId() <= server.getVersionId() && target.version.getVersionId() < s.version.getVersionId())
|
||||
target = s;
|
||||
}
|
||||
targetVersion = target;
|
||||
try{
|
||||
method = targetClass.getMethod(targetVersion.name, args);
|
||||
method.setAccessible(true);
|
||||
loaded = true;
|
||||
methodName = targetVersion.name;
|
||||
}catch(NullPointerException | NoSuchMethodException | SecurityException ex){
|
||||
System.out.println("[NBTAPI] Unable to find the method '" + targetVersion.name + "' in '" + targetClass.getSimpleName() + "' Enum: " + this); //NOSONAR This gets loaded before the logger is loaded
|
||||
}
|
||||
}
|
||||
|
||||
ReflectionMethod(Class<?> targetClass, Class<?>[] args, MinecraftVersion addedSince, Since... methodnames){
|
||||
this(targetClass, args, addedSince, null, methodnames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the method on a given target object using the given args.
|
||||
*
|
||||
* @param target
|
||||
* @param args
|
||||
* @return Value returned by the method
|
||||
*/
|
||||
public Object run(Object target, Object... args){
|
||||
if(method == null)
|
||||
throw new NbtApiException("Method not loaded! '" + this + "'");
|
||||
try{
|
||||
return method.invoke(target, args);
|
||||
}catch(Exception ex){
|
||||
throw new NbtApiException("Error while calling the method '" + methodName + "', loaded: " + loaded + ", Enum: " + this, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The MethodName, used in this Minecraft Version
|
||||
*/
|
||||
public String getMethodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Has this method been linked
|
||||
*/
|
||||
public boolean isLoaded() {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Is this method available in this Minecraft Version
|
||||
*/
|
||||
public boolean isCompatible() {
|
||||
return compatible;
|
||||
}
|
||||
|
||||
protected static class Since{
|
||||
public final MinecraftVersion version;
|
||||
public final String name;
|
||||
public Since(MinecraftVersion version, String name) {
|
||||
this.version = version;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
package com.songoda.epicenchants.utils.objects;
|
||||
|
||||
import com.songoda.core.nms.NmsManager;
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import com.songoda.epicenchants.objects.Placeholder;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.single.ConfigParser;
|
||||
import com.songoda.epicenchants.utils.single.GeneralUtils;
|
||||
import com.songoda.epicenchants.wrappers.EnchantmentWrapper;
|
||||
@ -15,7 +16,12 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.color;
|
||||
@ -259,7 +265,7 @@ public class ItemBuilder {
|
||||
}
|
||||
|
||||
public NBTItem nbt() {
|
||||
return new NBTItem(build());
|
||||
return NmsManager.getNbt().of(build());
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user