mirror of
				https://github.com/mcMMO-Dev/mcMMO.git
				synced 2025-11-04 02:53:43 +01:00 
			
		
		
		
	prevent simulateBlockBreak from calling itself fixes #5188
This commit is contained in:
		@@ -64,6 +64,13 @@ import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 */
 | 
			
		||||
public final class EventUtils {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * True when the current thread is already executing simulateBlockBreak().
 | 
			
		||||
     * Thread-local so parallel Folia regions / async tasks are isolated.
 | 
			
		||||
     */
 | 
			
		||||
    private static final ThreadLocal<Boolean> IN_FAKE_BREAK =
 | 
			
		||||
            ThreadLocal.withInitial(() -> false);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This is a static utility class, therefore we don't want any instances of this class. Making
 | 
			
		||||
     * the constructor private prevents accidents like that.
 | 
			
		||||
@@ -366,22 +373,31 @@ public final class EventUtils {
 | 
			
		||||
     * @param eventType The type of event to signal to other plugins
 | 
			
		||||
     * @return true if the event wasn't cancelled, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean simulateBlockBreak(Block block, Player player,
 | 
			
		||||
    private static boolean simulateBlockBreak(Block block, Player player,
 | 
			
		||||
            FakeBlockBreakEventType eventType) {
 | 
			
		||||
        PluginManager pluginManager = mcMMO.p.getServer().getPluginManager();
 | 
			
		||||
 | 
			
		||||
        FakeBlockDamageEvent damageEvent = new FakeBlockDamageEvent(player, block,
 | 
			
		||||
                player.getInventory().getItemInMainHand(), true);
 | 
			
		||||
        pluginManager.callEvent(damageEvent);
 | 
			
		||||
 | 
			
		||||
        BlockBreakEvent fakeBlockBreakEvent = null;
 | 
			
		||||
 | 
			
		||||
        switch (eventType) {
 | 
			
		||||
            case FAKE -> fakeBlockBreakEvent = new FakeBlockBreakEvent(block, player);
 | 
			
		||||
            case TREE_FELLER -> fakeBlockBreakEvent = new TreeFellerBlockBreakEvent(block, player);
 | 
			
		||||
        if (IN_FAKE_BREAK.get()) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        IN_FAKE_BREAK.set(true);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            final PluginManager pluginManager = mcMMO.p.getServer().getPluginManager();
 | 
			
		||||
 | 
			
		||||
            final FakeBlockDamageEvent damageEvent = new FakeBlockDamageEvent(player, block,
 | 
			
		||||
                    player.getInventory().getItemInMainHand(), true);
 | 
			
		||||
            pluginManager.callEvent(damageEvent);
 | 
			
		||||
 | 
			
		||||
            final BlockBreakEvent fakeBlockBreakEvent = switch (eventType) {
 | 
			
		||||
                case FAKE -> new FakeBlockBreakEvent(block, player);
 | 
			
		||||
                case TREE_FELLER -> new TreeFellerBlockBreakEvent(block, player);
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            pluginManager.callEvent(fakeBlockBreakEvent);
 | 
			
		||||
            return !damageEvent.isCancelled() && !fakeBlockBreakEvent.isCancelled();
 | 
			
		||||
        } finally {
 | 
			
		||||
            // always clear the flag
 | 
			
		||||
            IN_FAKE_BREAK.set(false);
 | 
			
		||||
        }
 | 
			
		||||
        pluginManager.callEvent(fakeBlockBreakEvent);
 | 
			
		||||
        return !damageEvent.isCancelled() && !fakeBlockBreakEvent.isCancelled();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void handlePartyTeleportEvent(Player teleportingPlayer, Player targetPlayer) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user