Slimefun

Slimefun

3M Downloads

Item Dupe with QuickShop & PlotSquared

balugaq opened this issue · 2 comments

commented

❗ 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

https://mclo.gs/JUppJ1U

📂 /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

commented

I'm sure that Slimefun vExperimental with the latest QuickShop & PlotSquared can also reproduce this bug.

I'll later explain how this bug produced.

commented

I noticed this bug at first in SlimefunGuguProject/Slimefun4#1071.
Then I found that the bug is caused by the QuickShop:

Source code

        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:

Souce 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:

  1. (Bukkit/Paper) Player left-clicked at output chest.
  2. (QuickShop) QuickShop thinks the player is trying to create a shop.
  3. (QuickShop) QuickShop created a FAKE BlockBreakEvent to check permission.
  4. ==(Slimefun) Slimefun handles the FAKE event and thinks the chest is going to be broke.
  5. ==(Slimefun) Slimefun drops items that are in the block inventory.
  6. (QuickShop) the FAKE event didn't be cancelled.
  7. (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.