Fixed item skin subtypes not giving back the item when taken off

This commit is contained in:
Jules 2024-04-25 18:28:33 -07:00
parent 215ee1582f
commit 2a88e22e39
3 changed files with 113 additions and 114 deletions

View File

@ -54,17 +54,6 @@ public class MMOItemReforger {
this(NBTItem.get(stack));
}
/**
* @param nbtItem If for any reason you already generated an NBTItem,
* you may pass it here to ease the performance of
* generating it again from the ItemStack.
* @param stack Useless parameter.
*/
@Deprecated
public MMOItemReforger(@Nullable ItemStack stack, @NotNull NBTItem nbtItem) {
this(nbtItem);
}
/**
* Create this reforger to handle all operations regarding RevID
* increases on any ItemStack, including: <br>
@ -435,6 +424,12 @@ public class MMOItemReforger {
//endregion
//region Deprecated API
@Deprecated
public MMOItemReforger(@Nullable ItemStack stack, @NotNull NBTItem nbtItem) {
this(nbtItem);
}
@Deprecated
public void update(@Nullable Player p, @NotNull ReforgeOptions options) {
reforge(options, p);

View File

@ -23,120 +23,123 @@ import org.bukkit.inventory.meta.SkullMeta;
import java.util.Random;
import java.util.logging.Level;
/**
* @deprecated Not used nor maintained
*/
@Deprecated
public class NoClipItem implements Listener {
private final Item item;
private final Item item;
/**
* Util class which creates an item which cannot be picked up. Item is
* removed if it tries to go through a nether portal
*
* @param loc
* Spawn location of the item
* @param item
* ItemStack used to summon the entity
*/
public NoClipItem(Location loc, ItemStack item) {
this.item = loc.getWorld().dropItem(loc, stripItemData(item));
this.item.setPickupDelay(1000000);
/**
* Util class which creates an item which cannot be picked up. Item is
* removed if it tries to go through a nether portal
*
* @param loc Spawn location of the item
* @param item ItemStack used to summon the entity
* @deprecated Not used nor maintained
*/
public NoClipItem(Location loc, ItemStack item) {
this.item = loc.getWorld().dropItem(loc, stripItemData(item));
this.item.setPickupDelay(1000000);
Bukkit.getPluginManager().registerEvents(this, MMOItems.plugin);
}
Bukkit.getPluginManager().registerEvents(this, MMOItems.plugin);
}
public Item getEntity() {
return item;
}
public Item getEntity() {
return item;
}
public void close() {
item.remove();
public void close() {
item.remove();
EntityPortalEnterEvent.getHandlerList().unregister(this);
InventoryPickupItemEvent.getHandlerList().unregister(this);
EntityPickupItemEvent.getHandlerList().unregister(this);
}
EntityPortalEnterEvent.getHandlerList().unregister(this);
InventoryPickupItemEvent.getHandlerList().unregister(this);
EntityPickupItemEvent.getHandlerList().unregister(this);
}
// Stops items from being picked up by hoppers/portals and then duping them.
@EventHandler(priority = EventPriority.LOWEST)
public void a(InventoryPickupItemEvent event) {
if (event.getItem().equals(item)) {
event.setCancelled(true);
close();
}
}
// Stops items from being picked up by hoppers/portals and then duping them.
@EventHandler(priority = EventPriority.LOWEST)
public void a(InventoryPickupItemEvent event) {
if (event.getItem().equals(item)) {
event.setCancelled(true);
close();
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void b(EntityPortalEnterEvent event) {
if (event.getEntity().equals(item)) {
close();
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void b(EntityPortalEnterEvent event) {
if (event.getEntity().equals(item)) {
close();
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void c(EntityPickupItemEvent event) {
if (event.getItem().equals(item)) {
close();
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void c(EntityPickupItemEvent event) {
if (event.getItem().equals(item)) {
close();
}
}
/*
* Method used to strip item data from the ItemStack.
*
* This creates a new ItemStack with only data needed for the item to look and work like normal
* such as its Material, Custom Model Data, Enchantments (Shiny look), Glow and Glow Color from its tier,
* skull textures, leather colors and also most importantly adds "MMOITEMS_NO_CLIP_ITEM" to
* its NBT so even *IF* the items are duped we can and server owners can detect these items super, super easily.
* https://i.imgur.com/oLjkeoD.png
*/
private ItemStack stripItemData(ItemStack oldItem) {
final NBTItem oldItemNBT = MythicLib.plugin.getVersion().getWrapper().getNBTItem(oldItem);
/*
* Method used to strip item data from the ItemStack.
*
* This creates a new ItemStack with only data needed for the item to look and work like normal
* such as its Material, Custom Model Data, Enchantments (Shiny look), Glow and Glow Color from its tier,
* skull textures, leather colors and also most importantly adds "MMOITEMS_NO_CLIP_ITEM" to
* its NBT so even *IF* the items are duped we can and server owners can detect these items super, super easily.
* https://i.imgur.com/oLjkeoD.png
*/
private ItemStack stripItemData(ItemStack oldItem) {
final NBTItem oldItemNBT = MythicLib.plugin.getVersion().getWrapper().getNBTItem(oldItem);
// Make new item.
final ItemStack newItem = new ItemStack(oldItem.getType());
final ItemMeta newItemMeta = newItem.getItemMeta();
newItem.setAmount(1);
// Make new item.
final ItemStack newItem = new ItemStack(oldItem.getType());
final ItemMeta newItemMeta = newItem.getItemMeta();
newItem.setAmount(1);
/*
* Copy Enchantments
* Adds Luck 0 if the item has any enchantments so it looks shiny.
* Hiding the enchantment doesn't really matter but thought it'll be better
* to look like a vanilla item if a player somehow picks it up and Luck 0 does nothing.
*/
if (oldItem.getItemMeta().hasEnchants()) {
newItemMeta.addEnchant(Enchantment.LUCK, 0, true);
newItemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
}
/*
* Copy Enchantments
* Adds Luck 0 if the item has any enchantments so it looks shiny.
* Hiding the enchantment doesn't really matter but thought it'll be better
* to look like a vanilla item if a player somehow picks it up and Luck 0 does nothing.
*/
if (oldItem.getItemMeta().hasEnchants()) {
newItemMeta.addEnchant(Enchantment.LUCK, 0, true);
newItemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
}
// Copy CustomModelData. Only if 1.14+
if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13) && oldItem.getItemMeta().hasCustomModelData() && oldItem.getItemMeta().getCustomModelData() != 0) {
newItemMeta.setCustomModelData(oldItem.getItemMeta().getCustomModelData());
}
// Copy CustomModelData. Only if 1.14+
if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13) && oldItem.getItemMeta().hasCustomModelData() && oldItem.getItemMeta().getCustomModelData() != 0) {
newItemMeta.setCustomModelData(oldItem.getItemMeta().getCustomModelData());
}
// Copy Skull textures
if (oldItem.getItemMeta() instanceof SkullMeta) try {
final Object oldProfile = MythicLib.plugin.getVersion().getWrapper().getProfile((SkullMeta) oldItem.getItemMeta());
MythicLib.plugin.getVersion().getWrapper().setProfile((SkullMeta) newItemMeta, oldProfile);
} catch (RuntimeException exception) {
MMOItems.plugin.getLogger().log(Level.WARNING, "Could not set skull texture on stripItemData method in the NoClipItem class. Please report this issue!");
}
// Copy Skull textures
if (oldItem.getItemMeta() instanceof SkullMeta) try {
final Object oldProfile = MythicLib.plugin.getVersion().getWrapper().getProfile((SkullMeta) oldItem.getItemMeta());
MythicLib.plugin.getVersion().getWrapper().setProfile((SkullMeta) newItemMeta, oldProfile);
} catch (RuntimeException exception) {
MMOItems.plugin.getLogger().log(Level.WARNING, "Could not set skull texture on stripItemData method in the NoClipItem class. Please report this issue!");
}
// Copy Leather colors
if (oldItem.getItemMeta() instanceof LeatherArmorMeta && newItemMeta instanceof LeatherArmorMeta) {
((LeatherArmorMeta) newItemMeta).setColor(((LeatherArmorMeta) oldItem.getItemMeta()).getColor());
}
// Copy Leather colors
if (oldItem.getItemMeta() instanceof LeatherArmorMeta && newItemMeta instanceof LeatherArmorMeta) {
((LeatherArmorMeta) newItemMeta).setColor(((LeatherArmorMeta) oldItem.getItemMeta()).getColor());
}
// Set ItemMeta and get item as NBTItem to continue work.
newItem.setItemMeta(newItemMeta);
final NBTItem newItemNBT = MythicLib.plugin.getVersion().getWrapper().getNBTItem(newItem);
// Set ItemMeta and get item as NBTItem to continue work.
newItem.setItemMeta(newItemMeta);
final NBTItem newItemNBT = MythicLib.plugin.getVersion().getWrapper().getNBTItem(newItem);
// Copy Tier for item Glow.
newItemNBT.addTag(new ItemTag("MMOITEMS_TIER", oldItemNBT.getString("MMOITEMS_TIER").trim().isEmpty() ? null : oldItemNBT.getString("MMOITEMS_TIER")));
// Copy Tier for item Glow.
newItemNBT.addTag(new ItemTag("MMOITEMS_TIER", oldItemNBT.getString("MMOITEMS_TIER").trim().isEmpty() ? null : oldItemNBT.getString("MMOITEMS_TIER")));
// Make them not stack together, we NEVER want them to stack. Was only used on Throw up.
final Random random = new Random();
newItemNBT.addTag(new ItemTag("MMOITEMS_NO_STACK", random.nextInt(Integer.MAX_VALUE)));
// Make them not stack together, we NEVER want them to stack. Was only used on Throw up.
final Random random = new Random();
newItemNBT.addTag(new ItemTag("MMOITEMS_NO_STACK", random.nextInt(Integer.MAX_VALUE)));
// Safety tag
newItemNBT.addTag(new ItemTag("MMOITEMS_NO_CLIP_ITEM", true));
// Safety tag
newItemNBT.addTag(new ItemTag("MMOITEMS_NO_CLIP_ITEM", true));
return newItemNBT.toItem();
}
return newItemNBT.toItem();
}
}

View File

@ -86,7 +86,7 @@ public class CanDeskin extends BooleanStat implements ConsumableItemInteraction
MythicLib.plugin.getVersion().getWrapper().setProfile((SkullMeta) targetItemMeta,
((SkullTextureData) originalMmoitem.getData(ItemStats.SKULL_TEXTURE)).getGameProfile());
// Update deskined item
// Update un-skined item
final ItemStack updated = target.getItem();
updated.setItemMeta(targetItemMeta);
updated.setType(originalItem.getType());
@ -94,14 +94,15 @@ public class CanDeskin extends BooleanStat implements ConsumableItemInteraction
// Give back the skin item
try {
// Try to find the skin item.
// This is for backwards compatibility as cases with SKIN subtypes were not handled
// in the past, inducing an unfixable data loss for item skins applied onto items
/*
* Try to find the skin item. This code is for backwards compatibility as
* cases with SKIN subtypes were not handled in the past, inducing an
* unfixable data loss for item skins applied onto items
*/
@Deprecated final String skinTypeId = target.getString(ItemSkin.SKIN_TYPE_TAG);
final Type type = Objects.requireNonNullElse(Type.get(skinTypeId), Type.SKIN);
Validate.notNull(type, "Could not find item type of applied skin");
final MMOItemTemplate template = MMOItems.plugin.getTemplates().getTemplateOrThrow(Type.SKIN, skinId);
Validate.notNull(template, "Could not find item template of applied skin");
final MMOItemTemplate template = MMOItems.plugin.getTemplates().getTemplateOrThrow(type, skinId);
Validate.notNull(template, "Could not find item template of applied skin, type used " + type.getName());
// Item found, giving it to the player
final MMOItem mmoitem = template.newBuilder(playerData.getRPG()).build();