<commit_before>package com.elmakers.mine.bukkit.action.builtin;

import com.elmakers.mine.bukkit.action.BaseSpellAction;
import com.elmakers.mine.bukkit.api.action.CastContext;
import com.elmakers.mine.bukkit.api.batch.Batch;
import com.elmakers.mine.bukkit.api.block.UndoList;
import com.elmakers.mine.bukkit.api.block.UndoQueue;
import com.elmakers.mine.bukkit.api.magic.Mage;
import com.elmakers.mine.bukkit.api.magic.MageController;
import com.elmakers.mine.bukkit.api.spell.SpellResult;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;

public class UndoAction extends BaseSpellAction
{
	private String undoListName;
    private int timeout;
    private int blockTimeout;
    private String targetSpellKey;
    private boolean targetSelf;
    private boolean targetDown;
    private boolean targetBlocks;
    private boolean targetOtherBlocks;
    private boolean cancel;
    private String adminPermission;
    private int undoOldest;
    private int undoToSize;

    // State
    private int undone;

    @Override
    public void prepare(CastContext context, ConfigurationSection parameters)
    {
        super.prepare(context, parameters);
        timeout = parameters.getInt("target_timeout", 0);
        blockTimeout = parameters.getInt("target_block_timeout", timeout);

        // TODO: Use a ContextAction instead?
        targetSelf = parameters.getBoolean("target_caster", false);
        targetDown = parameters.getBoolean("target_down", false);
        targetBlocks = parameters.getBoolean("target_blocks", true);
        targetOtherBlocks = parameters.getBoolean("target_other_blocks", false);
        cancel = parameters.getBoolean("cancel", true);
        targetSpellKey = parameters.getString("target_spell", null);
        adminPermission = parameters.getString("admin_permission", null);

        undoOldest = parameters.getInt("undo_oldest", 0);
        undoToSize = parameters.getInt("undo_to", 0);
    }
    @Override
    public void reset(CastContext context) {
        super.reset(context);
        undone = 0;
    }

    protected SpellResult performNew(CastContext context)
    {
        UndoList undoList = context.getUndoList();
        if (undoList.size() == 0)
        {
            return SpellResult.NO_ACTION;
        }

        boolean undid = false;
        while (context.getWorkAllowed() > 0) {
            if (undoToSize > 0 && undoList.size() <= undoToSize) break;

            if (undoList.undoNext(false) == null) break;
            undid = true;
            undone++;

            context.addWork(10);
            if (undoOldest > 0 && undone > undoOldest) {
                break;
            }
        }
        if (!undid) return SpellResult.NO_ACTION;

        return undoOldest == 0 || undone >= undoOldest ? SpellResult.CAST : SpellResult.PENDING;
    }

    @Override
	public SpellResult perform(CastContext context)
	{<commit_msg>Undo action can walk through Runnable lists as well as block changes<commit_after>package com.elmakers.mine.bukkit.action.builtin;

import com.elmakers.mine.bukkit.action.BaseSpellAction;
import com.elmakers.mine.bukkit.api.action.CastContext;
import com.elmakers.mine.bukkit.api.batch.Batch;
import com.elmakers.mine.bukkit.api.block.UndoList;
import com.elmakers.mine.bukkit.api.block.UndoQueue;
import com.elmakers.mine.bukkit.api.magic.Mage;
import com.elmakers.mine.bukkit.api.magic.MageController;
import com.elmakers.mine.bukkit.api.spell.SpellResult;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;

public class UndoAction extends BaseSpellAction
{
	private String undoListName;
    private int timeout;
    private int blockTimeout;
    private String targetSpellKey;
    private boolean targetSelf;
    private boolean targetDown;
    private boolean targetBlocks;
    private boolean targetOtherBlocks;
    private boolean cancel;
    private String adminPermission;
    private int undoOldest;
    private int undoToSize;

    // State
    private int undone;

    @Override
    public void prepare(CastContext context, ConfigurationSection parameters)
    {
        super.prepare(context, parameters);
        timeout = parameters.getInt("target_timeout", 0);
        blockTimeout = parameters.getInt("target_block_timeout", timeout);

        // TODO: Use a ContextAction instead?
        targetSelf = parameters.getBoolean("target_caster", false);
        targetDown = parameters.getBoolean("target_down", false);
        targetBlocks = parameters.getBoolean("target_blocks", true);
        targetOtherBlocks = parameters.getBoolean("target_other_blocks", false);
        cancel = parameters.getBoolean("cancel", true);
        targetSpellKey = parameters.getString("target_spell", null);
        adminPermission = parameters.getString("admin_permission", null);

        undoOldest = parameters.getInt("undo_oldest", 0);
        undoToSize = parameters.getInt("undo_to", 0);
    }
    @Override
    public void reset(CastContext context) {
        super.reset(context);
        undone = 0;
    }

    protected SpellResult performNew(CastContext context)
    {
        UndoList undoList = context.getUndoList();
        int totalSize = undoList.size() + undoList.getRunnableCount();
        if (totalSize == 0)
        {
            return SpellResult.NO_ACTION;
        }

        boolean undid = false;
        while (context.getWorkAllowed() > 0) {
            if (undoToSize > 0 && totalSize <= undoToSize) break;
            if (undoList.size() == 0) {
                if (undoList.undoNextRunnable() == null) break; 
            } else {
                if (undoList.undoNext(false) == null) break;
            }
            undid = true;
            undone++;

            context.addWork(10);
            if (undoOldest > 0 && undone > undoOldest) {
                break;
            }
        }
        if (!undid) return SpellResult.NO_ACTION;

        return undoOldest == 0 || undone >= undoOldest ? SpellResult.CAST : SpellResult.PENDING;
    }

    @Override
	public SpellResult perform(CastContext context)
	{
{'fraction_non_alphanumeric': 0.09863453815261045, 'fraction_numerical': 0.0036947791164658635, 'mean_word_length': 3.001285347043702, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, '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': '3230538', 'n_tokens_mistral': 1813, 'n_tokens_neox': 1737, 'n_words': 383}