mirror of
https://gitlab.com/phoenix-dvpmt/mmoitems.git
synced 2025-02-13 13:11:21 +01:00
NoClipItem now strips item data
Before when using abilities such as Item Bomb, Item Throw, Present Throw etc. we would just copy the item straight up and if the item somehow got picked up by something then players could dupe the item. This new strip method now takes all the item data away apart from what makes the item look unique like Material, Custom Model Data, Enchantments (Adds a hidden enchantment that does nothing to just show the shiny effect), Glow, Head Textures and leather colors. This new method also adds "MMOITEMS_NO_CLIP_ITEM" into the items NBT so we and servers owners can see and find these items IF they are duped/bugged in the future. Also added a little bit of extra protection for entity pickup and stopped some the items from being stackable and causing items. If the item is somehow picked up it will just look like a normal vanilla item https://i.imgur.com/oLjkeoD.png but hopefully that will never be the case of players getting this item but extra padding never hurts.
This commit is contained in:
parent
b2cd456daf
commit
402daf6cbb
@ -23,7 +23,6 @@ import net.Indyuce.mmoitems.stat.data.AbilityData;
|
|||||||
import net.mmogroup.mmolib.MMOLib;
|
import net.mmogroup.mmolib.MMOLib;
|
||||||
import net.mmogroup.mmolib.api.AttackResult;
|
import net.mmogroup.mmolib.api.AttackResult;
|
||||||
import net.mmogroup.mmolib.api.DamageType;
|
import net.mmogroup.mmolib.api.DamageType;
|
||||||
import net.mmogroup.mmolib.api.item.ItemTag;
|
|
||||||
|
|
||||||
public class Throw_Up extends Ability implements Listener {
|
public class Throw_Up extends Ability implements Listener {
|
||||||
public Throw_Up() {
|
public Throw_Up() {
|
||||||
@ -65,7 +64,7 @@ public class Throw_Up extends Ability implements Listener {
|
|||||||
|
|
||||||
loc.getWorld().playSound(loc, Sound.ENTITY_ZOMBIE_HURT, 1, 1);
|
loc.getWorld().playSound(loc, Sound.ENTITY_ZOMBIE_HURT, 1, 1);
|
||||||
|
|
||||||
NoClipItem item = new NoClipItem(stats.getPlayer().getLocation().add(0, 1.2, 0), MMOLib.plugin.getVersion().getWrapper().getNBTItem(new ItemStack(Material.ROTTEN_FLESH)).addTag(new ItemTag("noStack", random.nextInt(1000))).toItem());
|
NoClipItem item = new NoClipItem(stats.getPlayer().getLocation().add(0, 1.2, 0), MMOLib.plugin.getVersion().getWrapper().getNBTItem(new ItemStack(Material.ROTTEN_FLESH)).toItem());
|
||||||
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOItems.plugin, () -> item.close(), 40);
|
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOItems.plugin, () -> item.close(), 40);
|
||||||
item.getEntity().setVelocity(loc.getDirection().multiply(.8));
|
item.getEntity().setVelocity(loc.getDirection().multiply(.8));
|
||||||
stats.getPlayer().getWorld().spawnParticle(Particle.SMOKE_LARGE, stats.getPlayer().getLocation().add(0, 1.2, 0), 0, loc.getDirection().getX(), loc.getDirection().getY(), loc.getDirection().getZ(), 1);
|
stats.getPlayer().getWorld().spawnParticle(Particle.SMOKE_LARGE, stats.getPlayer().getLocation().add(0, 1.2, 0), 0, loc.getDirection().getX(), loc.getDirection().getY(), loc.getDirection().getZ(), 1);
|
||||||
|
@ -1,16 +1,31 @@
|
|||||||
package net.Indyuce.mmoitems.api.util;
|
package net.Indyuce.mmoitems.api.util;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.entity.Item;
|
import org.bukkit.entity.Item;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||||
import org.bukkit.event.entity.EntityPortalEnterEvent;
|
import org.bukkit.event.entity.EntityPortalEnterEvent;
|
||||||
import org.bukkit.event.inventory.InventoryPickupItemEvent;
|
import org.bukkit.event.inventory.InventoryPickupItemEvent;
|
||||||
|
import org.bukkit.inventory.ItemFlag;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.inventory.meta.LeatherArmorMeta;
|
||||||
|
import org.bukkit.inventory.meta.SkullMeta;
|
||||||
|
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
|
||||||
import net.Indyuce.mmoitems.MMOItems;
|
import net.Indyuce.mmoitems.MMOItems;
|
||||||
|
import net.mmogroup.mmolib.MMOLib;
|
||||||
|
import net.mmogroup.mmolib.api.item.ItemTag;
|
||||||
|
import net.mmogroup.mmolib.api.item.NBTItem;
|
||||||
|
|
||||||
public class NoClipItem implements Listener {
|
public class NoClipItem implements Listener {
|
||||||
private final Item item;
|
private final Item item;
|
||||||
@ -18,16 +33,14 @@ public class NoClipItem implements Listener {
|
|||||||
/**
|
/**
|
||||||
* Util class which creates an item which cannot be picked up. Item is
|
* Util class which creates an item which cannot be picked up. Item is
|
||||||
* removed if it tries to go through a nether portal
|
* removed if it tries to go through a nether portal
|
||||||
*
|
*
|
||||||
* @param loc
|
* @param loc
|
||||||
* Spawn location of the item
|
* Spawn location of the item
|
||||||
* @param item
|
* @param item
|
||||||
* ItemStack used to summon the entity
|
* ItemStack used to summon the entity
|
||||||
*/
|
*/
|
||||||
public NoClipItem(Location loc, ItemStack item) {
|
public NoClipItem(Location loc, ItemStack item) {
|
||||||
item.setAmount(1);
|
this.item = loc.getWorld().dropItem(loc, stripItemData(item));
|
||||||
|
|
||||||
this.item = loc.getWorld().dropItem(loc, item);
|
|
||||||
this.item.setPickupDelay(1000000);
|
this.item.setPickupDelay(1000000);
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOItems.plugin);
|
Bukkit.getPluginManager().registerEvents(this, MMOItems.plugin);
|
||||||
@ -42,9 +55,10 @@ public class NoClipItem implements Listener {
|
|||||||
|
|
||||||
EntityPortalEnterEvent.getHandlerList().unregister(this);
|
EntityPortalEnterEvent.getHandlerList().unregister(this);
|
||||||
InventoryPickupItemEvent.getHandlerList().unregister(this);
|
InventoryPickupItemEvent.getHandlerList().unregister(this);
|
||||||
|
EntityPickupItemEvent.getHandlerList().unregister(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stops items from being picked up by hoppers and portals and then duping them.
|
// Stops items from being picked up by hoppers/portals and then duping them.
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false)
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false)
|
||||||
public void a(InventoryPickupItemEvent event) {
|
public void a(InventoryPickupItemEvent event) {
|
||||||
if (event.getItem().equals(item)) {
|
if (event.getItem().equals(item)) {
|
||||||
@ -55,7 +69,85 @@ public class NoClipItem implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false)
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false)
|
||||||
public void b(EntityPortalEnterEvent event) {
|
public void b(EntityPortalEnterEvent event) {
|
||||||
if (event.getEntity().equals(item))
|
if (event.getEntity().equals(item)) {
|
||||||
close();
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false)
|
||||||
|
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 = MMOLib.plugin.getVersion().getWrapper().getNBTItem(oldItem);
|
||||||
|
|
||||||
|
// 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 CustomModelData. Only if 1.14+
|
||||||
|
if (MMOLib.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 Field oldProfileField = oldItem.getItemMeta().getClass().getDeclaredField("profile");
|
||||||
|
oldProfileField.setAccessible(true);
|
||||||
|
final GameProfile oldProfile = (GameProfile) oldProfileField.get(oldItem.getItemMeta());
|
||||||
|
|
||||||
|
final Field profileField = newItemMeta.getClass().getDeclaredField("profile");
|
||||||
|
profileField.setAccessible(true);
|
||||||
|
profileField.set(newItemMeta, oldProfile);
|
||||||
|
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set ItemMeta and get item as NBTItem to continue work.
|
||||||
|
newItem.setItemMeta(newItemMeta);
|
||||||
|
final NBTItem newItemNBT = MMOLib.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")));
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
return newItemNBT.toItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user