
Item Dupe with QuickShop & PlotSquared
balugaq opened this issue · 2 comments
❗ Checklist
- I am using the official english version of Slimefun and did not modify the jar.
- I downloaded the official version from the new build site Blob Builds.
- I am using an up to date "DEV" (not "RC") version of Slimefun.
- I am aware that issues related to Slimefun addons need to be reported on their bug trackers and not here.
- I searched for similar open issues and could not find an existing bug report on this.
📍 Description
See video ↓
📑 Reproduction Steps
Video:
QQ2025714-22219.mp4
💡 Expected Behavior
Items shouldn't be duped...
📷 Screenshots / Videos
^
📜 Server Log
📂 /error-reports/
folder
No
💻 Server Software
Paper
🎮 Minecraft Version
1.20.x
⭐ Slimefun version
Slimefun vDev - 1160
(The latest version now)
🧭 Other plugins
QuickShop-Hikari v6.2.0.9-RELEASE-1
PlotSquared v7.5.5-SNAPSHOT
I'm sure that Slimefun vExperimental with the latest QuickShop & PlotSquared can also reproduce this bug.
I'll later explain how this bug produced.
I noticed this bug at first in SlimefunGuguProject/Slimefun4#1071.
Then I found that the bug is caused by the QuickShop:
beMainHand = new BlockBreakEvent(block, player) {
@Override
public void setCancelled(boolean cancel) {
//tracking cancel plugin
if (cancel && !isCancelled()) {
Util.debugLog("An plugin blocked the protection checking event! See this stacktrace:");
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
Util.debugLog(element.getClassName() + "." + element.getMethodName() + "(" + element.getLineNumber() + ")");
}
isCanBuild.setMessage(Thread.currentThread().getStackTrace()[2].getClassName());
out:
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
for (RegisteredListener listener : getHandlerList().getRegisteredListeners()) {
if (listener.getListener().getClass().getName().equals(element.getClassName())) {
isCanBuild.setResult(false);
isCanBuild.setMessage(listener.getPlugin().getName());
break out;
}
}
}
}
super.setCancelled(cancel);
}
};
In this code, Quickshop created a BlockBreakEvent aiming to check permission, which is a FAKE event. But this code actually needs another BlockBreakEvent to trigger. That caused Slimefun handles the block break again. See BlockListener.
But m1919810 found that Slimefun thinks the BlockBreakEvent will be cancelled in any case. In this code:
@Override
@ParametersAreNonnullByDefault
public void onPlayerBreak(BlockBreakEvent e, ItemStack item, List<ItemStack> drops) {
// Fixes #2906 - Spigot being buggy as always...
if (!PaperLib.isPaper()) {
return;
}
Block b = e.getBlock();
BlockState state = PaperLib.getBlockState(b, false).getState();
if (blockStateClass.isInstance(state)) {
T inventoryHolder = blockStateClass.cast(state);
for (ItemStack stack : getInventory(inventoryHolder)) {
if (stack != null && !stack.getType().isAir()) {
drops.add(stack);
}
}
}
}
We can see that Slimefun only does drops.add(stack)
. Items actually are still alive in the block inventory after dropping.
So the bug might be produced like this:
- (Bukkit/Paper) Player left-clicked at output chest.
- (QuickShop) QuickShop thinks the player is trying to create a shop.
- (QuickShop) QuickShop created a FAKE BlockBreakEvent to check permission.
- ==(Slimefun) Slimefun handles the FAKE event and thinks the chest is going to be broke.
- ==(Slimefun) Slimefun drops items that are in the block inventory.
- (QuickShop) the FAKE event didn't be cancelled.
- (QuickShop) QuickShop created a shop at the chest.
Later, mcchampions fixed this bug in SlimefunGuguProject/Slimefun4#1075 and it works. Items couldn't be duped again.
That's all. If you have any questions, please point them out.