diff --git a/CHANGELOG.md b/CHANGELOG.md index 03c6fb6ab..683df2e4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -93,6 +93,7 @@ * Fixed "korean" showing up as "null" * Fixed an issue with moving androids getting stuck * Fixed Cargo nodes sometimes preventing chunks from unloading +* Fixed #2081 ## Release Candidate 13 (16 Jun 2020) https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#13 diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/exceptions/WrongItemStackException.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/exceptions/WrongItemStackException.java new file mode 100644 index 000000000..9b8c647ec --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/exceptions/WrongItemStackException.java @@ -0,0 +1,36 @@ +package io.github.thebusybiscuit.slimefun4.api.exceptions; + +import org.bukkit.inventory.ItemStack; + +import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; + +/** + * A {@link WrongItemStackException} is thrown when someone tries to alter an {@link ItemStack} + * but actually wanted to alter a different one. + * + * If for example a {@link DamageableItem} accidentally damages the original {@link SlimefunItem} + * instead of the held {@link ItemStack}, this will be thrown. + * + * @author TheBusyBiscuit + * + * @see SlimefunItemStack + * @see SlimefunItem + * + */ +public class WrongItemStackException extends RuntimeException { + + private static final long serialVersionUID = 9144658137363309071L; + + /** + * This constructs a new {@link WrongItemStackException} with the given error context. + * + * @param message + * An error message to display + */ + public WrongItemStackException(String message) { + super("You probably wanted alter a different ItemStack: " + message); + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosiveTool.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosiveTool.java index 0fcc52905..2ad1cb1b2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosiveTool.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosiveTool.java @@ -21,10 +21,10 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem; import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SimpleSlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.api.BlockStorage; @@ -63,7 +63,7 @@ class ExplosiveTool extends SimpleSlimefunItem implements Not b.getWorld().playSound(b.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 0.2F, 1F); List blocks = findBlocks(b); - breakBlocks(p, b, blocks, fortune, drops); + breakBlocks(p, item, b, blocks, fortune, drops); } return true; @@ -75,7 +75,7 @@ class ExplosiveTool extends SimpleSlimefunItem implements Not }; } - private void breakBlocks(Player p, Block b, List blocks, int fortune, List drops) { + private void breakBlocks(Player p, ItemStack item, Block b, List blocks, int fortune, List drops) { if (callExplosionEvent.getValue().booleanValue()) { BlockExplodeEvent blockExplodeEvent = new BlockExplodeEvent(b, blocks, 0); Bukkit.getServer().getPluginManager().callEvent(blockExplodeEvent); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java index 32f22f887..4877a3161 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java @@ -24,6 +24,7 @@ import io.github.thebusybiscuit.slimefun4.api.exceptions.IdConflictException; import io.github.thebusybiscuit.slimefun4.api.exceptions.IncompatibleItemHandlerException; import io.github.thebusybiscuit.slimefun4.api.exceptions.MissingDependencyException; import io.github.thebusybiscuit.slimefun4.api.exceptions.UnregisteredItemException; +import io.github.thebusybiscuit.slimefun4.api.exceptions.WrongItemStackException; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemState; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; @@ -409,6 +410,10 @@ public class SlimefunItem implements Placeable { state = ItemState.DISABLED; } + if (item instanceof SlimefunItemStack && isItemStackImmutable()) { + ((SlimefunItemStack) item).lock(); + } + postRegister(); if (SlimefunPlugin.getRegistry().isAutoLoadingEnabled() && state == ItemState.ENABLED) { @@ -442,6 +447,20 @@ public class SlimefunItem implements Placeable { } } + /** + * This method returns whether the original {@link SlimefunItemStack} of this + * {@link SlimefunItem} is immutable. + * + * If true is returned, then any changes to the original {@link SlimefunItemStack} + * will be rejected with a {@link WrongItemStackException}. + * This ensures integrity so developers don't accidentally damage the wrong {@link ItemStack}. + * + * @return Whether the original {@link SlimefunItemStack} is immutable. + */ + protected boolean isItemStackImmutable() { + return true; + } + /** * This method checks recursively for all {@link Class} parents to look for any {@link Deprecated} * elements. diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java b/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java index e49e68732..ae451a9b5 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java @@ -24,6 +24,7 @@ import io.github.thebusybiscuit.cscorelib2.item.ImmutableItemMeta; import io.github.thebusybiscuit.cscorelib2.skull.SkullItem; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.exceptions.PrematureCodeException; +import io.github.thebusybiscuit.slimefun4.api.exceptions.WrongItemStackException; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; @@ -34,6 +35,7 @@ public class SlimefunItemStack extends CustomItem { private String id; private ImmutableItemMeta immutableMeta; + private boolean locked = false; private String texture = null; public SlimefunItemStack(String id, Material type, String name, String... lore) { @@ -206,11 +208,34 @@ public class SlimefunItemStack extends CustomItem { @Override public boolean setItemMeta(ItemMeta meta) { + validate(); immutableMeta = new ImmutableItemMeta(meta); return super.setItemMeta(meta); } + @Override + public void setType(Material type) { + validate(); + super.setType(type); + } + + @Override + public void setAmount(int amount) { + validate(); + super.setAmount(amount); + } + + private void validate() { + if (locked) { + throw new WrongItemStackException(id + " is not mutable."); + } + } + + public void lock() { + locked = true; + } + @Override public ItemStack clone() { return new SlimefunItemStack(id, this);