PotatoCraft-Studio / QuickShop-Reremake

QuickShop-Reremake is a **FREE** shop plugin that allows players to easily sell/buy any items from a chest without any commands. In fact, none of the commands that QuickShop-Reremake provides are ever needed by a player.
GNU General Public License v3.0
69 stars 78 forks source link

[BUG] crash problem #323

Closed twseer67875 closed 1 year ago

twseer67875 commented 1 year ago

Description

When I try to execute the following code and setSignText(), the server crashes directly, I don’t know why

package com.cocobeen.Listener;

import com.cocobeen.QuickShopLimitPlugin;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Sign;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.maxgamer.quickshop.api.chat.ComponentPackage;
import org.maxgamer.quickshop.api.event.ShopSignUpdateEvent;
import org.maxgamer.quickshop.api.shop.Shop;

import java.util.List;

public class ShopSignUpdateListener implements Listener {

    @EventHandler
    public void ShopSignUpdate(ShopSignUpdateEvent event){
        Shop shop = event.getShop();

        Block block = shop.getLocation().getBlock();

        if (shop.getRemainingStock() != 0){
            for (BlockFace face : QuickShopLimitPlugin.faces){
                Block sign_block = block.getRelative(face);
                Material material = sign_block.getType();
                if (material.name().contains("SIGN")){
                    Sign sign = (Sign) sign_block.getState();
                    String line1 = PlainTextComponentSerializer.plainText().serialize(sign.line(0));
                    String line2 = PlainTextComponentSerializer.plainText().serialize(sign.line(1));

                    int limit = isInt(line2);

                    if (line1.equals("[qslimit]") && limit != 0){
                        List<ComponentPackage> sign_list = event.getShop().getSignText("zh_tw");

                        String limit_message = "";

                        if (shop.isSelling()){
                            limit_message = "(限購" + limit + "個)";
                        }
                        else {
                            limit_message = "(限售" + limit + "個)";
                        }
                        TextComponent component = new TextComponent(sign_list.get(1).getComponents()[1].toPlainText() + limit_message);
                        sign_list.set(1, new ComponentPackage(component));
                        event.getShop().setSignText(sign_list);
                    }
                }
            }
        }
    }

    private int isInt(String IntString){
        try {
            return Integer.parseInt(IntString);
        }
        catch (NumberFormatException exception){
            return 0;
        }
    }
}

Steps to reproduce

1.Execute the above code 2.Trigger the ShopSignUpdateEvent 3.boom

Expected Behaviour

Will not crash and modify the sign message normally

Screenshots

image image

/qs paste URL

https://paste.helpch.at/raw/vuxedogesi

Additional Context

This server is running Paper version git-Paper-307 (MC: 1.19.2) (Implementing API version 1.19.2-R0.1-SNAPSHOT) (Git: 476ef25)

twseer67875 commented 1 year ago

I am trying to find the approximate reason. It seems that ShopSignUpdateEvent will be triggered again after using setSignText(), resulting in a situation similar to an infinite loop. I don’t understand why setSignText() must be triggered again after use. ShopSignUpdateEvent, I don't understand why it is designed like this

sandtechnology commented 1 year ago

That's why I said change the sign directly, and setSignText method should result the sign update event, right? So that the infinite loop, if you want to use this anyway, you can simply check if the sign has applied the text you wanted

twseer67875 commented 1 year ago

That's why I said change the sign directly, and setSignText method should result the sign update event, right? So that the infinite loop, if you want to use this anyway, you can simply check if the sign has applied the text you wanted

I've already tried modifying Sign directly using the following method, but still nothing works

event.getSign().line(1, Component.text("example"));

I also tried to compare the strings between each other, but I found that as long as setSignText(); is used and ShopSignUpdateEvent is triggered, the Sign sent back to me by the event will always be the default Sign Text.

sandtechnology commented 1 year ago

That's why I said change the sign directly, and setSignText method should result the sign update event, right? So that the infinite loop, if you want to use this anyway, you can simply check if the sign has applied the text you wanted

I've already tried modifying Sign directly using the following method, but still nothing works

event.getSign().line(1, Component.text("example"));

I also tried to compare the strings between each other, but I found that as long as setSignText(); is used and ShopSignUpdateEvent is triggered, the Sign sent back to me by the event will always be the default Sign Text.

you need to use event.getSign().update(true) to make it take effect

SupportNL commented 1 year ago

I get the following error message! Version 1.19.4-518:

[16:49:40 WARN]: [QuickShop] [FATAL] Signature Verify: Failed to validate digital signature! Security may be compromised! [16:49:40 ERROR]: [QuickShop] [Security Risk Detected] QuickShop forcing crash the server for security, contact the developer for details. [16:49:40 WARN]: [QuickShop] [Security Risk Detected] To get more details, please check: file:/home/container/plugins/QuickShop/3780b208-46ff-4ebf-b8c1-89fe762dc8b8.security.letter.txt

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.