<commit_before>package com.elmakers.mine.bukkit.magic.listener;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import javax.annotation.Nullable;

import org.bukkit.Chunk;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;

import com.elmakers.mine.bukkit.api.block.UndoList;
import com.elmakers.mine.bukkit.api.magic.Mage;
import com.elmakers.mine.bukkit.magic.MagicController;

public class ExplosionController implements Listener {
    private final MagicController controller;
    private int    maxTNTPerChunk = 0;
    private int autoRollbackDuration = 10000;
    private double autoRollbackSpeed = 2;
    private Set<EntityType> rollbackExplosions = new HashSet<>();

    public ExplosionController(MagicController controller) {
        this.controller = controller;
    }

    public void loadProperties(ConfigurationSection properties) {
        maxTNTPerChunk = properties.getInt("max_tnt_per_chunk", 0);
        autoRollbackDuration = properties.getInt("auto_rollback_duration", 10000);
        autoRollbackSpeed = properties.getDouble("auto_rollback_speed", 2);
        rollbackExplosions.clear();
        Collection<String> typeNames = properties.getStringList("auto_rollback_explosions");
        if (typeNames != null) {
            for (String typeName : typeNames) {
                try {
                    EntityType entityType = EntityType.valueOf(typeName.toUpperCase());
                    rollbackExplosions.add(entityType);
                } catch (Exception ex) {
                    controller.getLogger().warning("Failed to parse entity type: " + typeName + " in auto_rollback_explosions");
                }
            }
        }
    }

    @Nullable
    protected UndoList getExplosionUndo(Entity explodingEntity) {
        UndoList blockList = controller.getEntityUndo(explodingEntity);
        if (blockList == null && autoRollbackDuration > 0 && rollbackExplosions.contains(explodingEntity.getType())) {
            Mage mage = controller.getMage(explodingEntity);
            blockList = new com.elmakers.mine.bukkit.block.UndoList(mage, "Explosion (" + explodingEntity.getType().name() + ")");
            blockList.setScheduleUndo(autoRollbackDuration);
            blockList.setUndoSpeed(autoRollbackSpeed);
            mage.prepareForUndo(blockList);
        }
        return blockList;
    }

    @EventHandler(priority = EventPriority.LOWEST)
    public void onEntityExplode(EntityExplodeEvent event) {
        Entity explodingEntity = event.getEntity();<commit_msg>Don't re-use an undone UndoList for explosion undo Hoping this fixes creeper explosions not always getting rolled back<commit_after>package com.elmakers.mine.bukkit.magic.listener;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import javax.annotation.Nullable;

import org.bukkit.Chunk;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;

import com.elmakers.mine.bukkit.api.block.UndoList;
import com.elmakers.mine.bukkit.api.magic.Mage;
import com.elmakers.mine.bukkit.magic.MagicController;

public class ExplosionController implements Listener {
    private final MagicController controller;
    private int    maxTNTPerChunk = 0;
    private int autoRollbackDuration = 10000;
    private double autoRollbackSpeed = 2;
    private Set<EntityType> rollbackExplosions = new HashSet<>();

    public ExplosionController(MagicController controller) {
        this.controller = controller;
    }

    public void loadProperties(ConfigurationSection properties) {
        maxTNTPerChunk = properties.getInt("max_tnt_per_chunk", 0);
        autoRollbackDuration = properties.getInt("auto_rollback_duration", 10000);
        autoRollbackSpeed = properties.getDouble("auto_rollback_speed", 2);
        rollbackExplosions.clear();
        Collection<String> typeNames = properties.getStringList("auto_rollback_explosions");
        if (typeNames != null) {
            for (String typeName : typeNames) {
                try {
                    EntityType entityType = EntityType.valueOf(typeName.toUpperCase());
                    rollbackExplosions.add(entityType);
                } catch (Exception ex) {
                    controller.getLogger().warning("Failed to parse entity type: " + typeName + " in auto_rollback_explosions");
                }
            }
        }
    }

    @Nullable
    protected UndoList getExplosionUndo(Entity explodingEntity) {
        UndoList blockList = controller.getEntityUndo(explodingEntity);
        if (blockList != null && blockList.isUndone()) {
            blockList = null;
        }
        if (blockList == null && autoRollbackDuration > 0 && rollbackExplosions.contains(explodingEntity.getType())) {
            Mage mage = controller.getMage(explodingEntity);
            blockList = new com.elmakers.mine.bukkit.block.UndoList(mage, "Explosion (" + explodingEntity.getType().name() + ")");
            blockList.setScheduleUndo(autoRollbackDuration);
            blockList.setUndoSpeed(autoRollbackSpeed);
            mage.prepareForUndo(blockList);
        }
        return blockList;
    }

    @EventHandler(priority = EventPriority.LOWEST)
    public void onEntityExplode(EntityExplodeEvent event) {
        Entity explodingEntity = event.getEntity();
{'fraction_non_alphanumeric': 0.09408324733402133, 'fraction_numerical': 0.005159958720330237, 'mean_word_length': 3.3820648078372266, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5455514', 'n_tokens_mistral': 1690, 'n_tokens_neox': 1567, 'n_words': 304}