<commit_before>package au.com.mineauz.minigames.blockRecorder;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.Chest;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Animals;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.minecart.HopperMinecart;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.block.BlockSpreadEvent;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.vehicle.VehicleCreateEvent;
import org.bukkit.event.vehicle.VehicleDestroyEvent;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;

import com.google.common.collect.Lists;

import au.com.mineauz.minigames.MinigamePlayer;
import au.com.mineauz.minigames.MinigameUtils;
import au.com.mineauz.minigames.Minigames;
import au.com.mineauz.minigames.menu.Callback;
import au.com.mineauz.minigames.minigame.Minigame;
import au.com.mineauz.minigames.minigame.MinigameState;

public class RecorderData implements Listener{
	private static Minigames plugin;
	
	private Minigame minigame;
	private boolean whitelistMode = false;
	private List<Material> wbBlocks = new ArrayList<Material>();
	private boolean hasCreatedRegenBlocks = false;
	
	private Map<String, BlockData> blockdata;
	private Map<Integer, EntityData> entdata;
	
	private static List<Material> physBlocks = new ArrayList<Material>();
	
	static{
		physBlocks.add(Material.TORCH);
		physBlocks.add(Material.SIGN_POST);
		physBlocks.add(Material.WALL_SIGN);
		physBlocks.add(Material.TRIPWIRE);
		physBlocks.add(Material.RAILS);
		physBlocks.add(Material.POWERED_RAIL);
		physBlocks.add(Material.ACTIVATOR_RAIL);
		physBlocks.add(Material.REDSTONE_WIRE);
		physBlocks.add(Material.REDSTONE_TORCH_OFF);
		physBlocks.add(Material.REDSTONE_TORCH_ON);
		physBlocks.add(Material.SAPLING);
		physBlocks.add(Material.RED_ROSE);
		physBlocks.add(Material.YELLOW_FLOWER);
		physBlocks.add(Material.WOOD_PLATE);
		physBlocks.add(Material.STONE_PLATE);
		physBlocks.add(Material.GOLD_PLATE);
		physBlocks.add(Material.IRON_PLATE);
		physBlocks.add(Material.STONE_BUTTON);
		physBlocks.add(Material.WOOD_BUTTON);
		physBlocks.add(Material.LEVER);
		physBlocks.add(Material.LADDER);
		physBlocks.add(Material.IRON_DOOR);
		physBlocks.add(Material.WOODEN_DOOR);
		physBlocks.add(Material.RED_MUSHROOM);
		physBlocks.add(Material.BROWN_MUSHROOM);
		physBlocks.add(Material.DOUBLE_PLANT);
		physBlocks.add(Material.FLOWER_POT);
		physBlocks.add(Material.WATER_LILY);
		physBlocks.add(Material.TRIPWIRE_HOOK);
		physBlocks.add(Material.TRAP_DOOR);
		physBlocks.add(Material.CARPET);
		physBlocks.add(Material.LONG_GRASS);
		physBlocks.add(Material.DEAD_BUSH);
		physBlocks.add(Material.REDSTONE_COMPARATOR_ON);
		physBlocks.add(Material.REDSTONE_COMPARATOR_OFF);
		physBlocks.add(Material.DIODE_BLOCK_OFF);
		physBlocks.add(Material.DIODE_BLOCK_ON);
		physBlocks.add(Material.WATER);
		physBlocks.add(Material.LAVA);
		physBlocks.add(Material.STATIONARY_WATER);
		physBlocks.add(Material.STATIONARY_LAVA);
		physBlocks.add(Material.ANVIL);
		physBlocks.add(Material.DRAGON_EGG);
		physBlocks.add(Material.SKULL);
	}
	
	public RecorderData(Minigame minigame){
		plugin = Minigames.plugin;
		
		this.minigame = minigame;
		blockdata = new HashMap<String, BlockData>();
		entdata = new HashMap<Integer, EntityData>();
		
//		plugin.getServer().getPluginManager().registerEvents(this, plugin);
	}
	
	public void setWhitelistMode(boolean bool){
		whitelistMode = bool;
	}
	
	public boolean getWhitelistMode(){
		return whitelistMode;
	}
	
	public Callback<Boolean> getWhitelistModeCallback(){
		return new Callback<Boolean>() {

			@Override
			public void setValue(Boolean value) {
				whitelistMode = value;
			}

			@Override
			public Boolean getValue() {
				return whitelistMode;
			}
		};
	}
	
	public void addWBBlock(Material mat){
		wbBlocks.add(mat);
	}
	
	public List<Material> getWBBlocks(){
		return wbBlocks;
	}
	
	public boolean removeWBBlock(Material mat){
		if(wbBlocks.contains(mat)){
			wbBlocks.remove(mat);
			return true;
		}
		return false;
	}
	
	public boolean hasCreatedRegenBlocks(){
		return hasCreatedRegenBlocks;
	}
	
	public void setCreatedRegenBlocks(boolean bool){
		hasCreatedRegenBlocks = bool;
	}
	
	public Minigame getMinigame(){
		return minigame;
	}
	
	public BlockData addBlock(Block block, MinigamePlayer modifier){
		return addBlock(block.getState(), modifier);
	}
	
	public BlockData addBlock(BlockState block, MinigamePlayer modifier){
		BlockData bdata = new BlockData(block, modifier);
		String sloc = String.valueOf(bdata.getLocation().getBlockX()) + ":" + bdata.getLocation().getBlockY() + ":" + bdata.getLocation().getBlockZ();
		if(!blockdata.containsKey(sloc)){
			if(block.getType() == Material.CHEST){
				Chest chest = (Chest) block;
				if(chest.getInventory().getSize() > 27){
					Location loc = block.getLocation().clone();
					boolean isRight = false;
					BlockFace dir = ((org.bukkit.material.Chest)chest.getData()).getFacing();
					BlockData secondChest = null;
					//West = -z; East = +z; North = +x; South = -x;
					if(dir == BlockFace.NORTH){
						loc.setX(loc.getX() + 1);
						if(loc.getBlock().getType() == Material.CHEST){
							isRight = true;
						}
						secondChest = addBlock(loc.getBlock().getState(), modifier);
					}
					else if(dir == BlockFace.SOUTH){
						loc.setX(loc.getX() - 1);
						if(loc.getBlock().getType() == Material.CHEST){
							isRight = true;
						}
						secondChest = addBlock(loc.getBlock().getState(), modifier);
					}
					else if(dir == BlockFace.WEST){
						loc.setZ(loc.getZ() - 1);
						if(loc.getBlock().getType() == Material.CHEST){
							isRight = true;
						}
						secondChest = addBlock(loc.getBlock().getState(), modifier);
					}
					else if(dir == BlockFace.EAST){
						loc.setZ(loc.getZ() + 1);
						if(loc.getBlock().getType() == Material.CHEST){
							isRight = true;
						}
						secondChest = addBlock(loc.getBlock().getState(), modifier);
					}
					
					if(!isRight){
						ItemStack[] items = new ItemStack[chest.getInventory().getContents().length];
						for(int i = 0; i < items.length; i++){
							if(chest.getInventory().getContents()[i] != null)
								items[i] = chest.getInventory().getContents()[i].clone();
						}
						bdata.setItems(items);
						if(minigame.isRandomizeChests())
							bdata.randomizeContents(minigame.getMinChestRandom(), minigame.getMaxChestRandom());
					}
					else{
						if(secondChest.getItems() == null){
							ItemStack[] items = new ItemStack[chest.getInventory().getContents().length];
							for(int i = 0; i < items.length; i++){
								if(chest.getInventory().getContents()[i] != null)
									items[i] = chest.getInventory().getContents()[i].clone();
							}
							secondChest.setItems(items);
							if(minigame.isRandomizeChests())
								secondChest.randomizeContents(minigame.getMinChestRandom(), minigame.getMaxChestRandom());
						}
					}
				}
				else{
					ItemStack[] items = new ItemStack[chest.getInventory().getContents().length];
					for(int i = 0; i < items.length; i++){
						if(chest.getInventory().getContents()[i] != null)
							items[i] = chest.getInventory().getContents()[i].clone();
					}
					bdata.setItems(items);
					if(minigame.isRandomizeChests())
						bdata.randomizeContents(minigame.getMinChestRandom(), minigame.getMaxChestRandom());
				}
			}
			else if(block instanceof InventoryHolder){
				InventoryHolder inv = (InventoryHolder) block;
				ItemStack[] items = new ItemStack[inv.getInventory().getContents().length];
				for(int i = 0; i < items.length; i++){
					if(inv.getInventory().getContents()[i] != null)
						items[i] = inv.getInventory().getContents()[i].clone();
				}
				bdata.setItems(items);
			}
			else if(block.getType() == Material.FLOWER_POT){
				bdata.setSpecialData("contents", block.getData());
			}
			
			blockdata.put(sloc, bdata);
			return bdata;
		}
		else{
			if(block.getType() != Material.CHEST || !blockdata.get(sloc).hasRandomized())
				blockdata.get(sloc).setModifier(modifier);
			return blockdata.get(sloc);
		}
	}
	
	public void addEntity(Entity ent, MinigamePlayer player, boolean created){
		EntityData edata = new EntityData(ent, player, created);
		entdata.put(ent.getEntityId(), edata);
	}
	
	public boolean hasEntity(Entity ent){
        return entdata.containsKey(ent.getEntityId());
    }
	
	public boolean hasBlock(Block block){
		String sloc = String.valueOf(block.getLocation().getBlockX()) + ":" + block.getLocation().getBlockY() + ":" + block.getLocation().getBlockZ();
        return blockdata.containsKey(sloc);
    }
	
	public void restoreAll(MinigamePlayer modifier) {
		if (!blockdata.isEmpty()) {
			restoreBlocks(modifier);
		}
		
		if (!entdata.isEmpty()) {
			restoreEntities(modifier);
		}
	}
	
	public void restoreBlocks(){
//		saveAllBlockData();
		restoreBlocks(null);
	}
	
	public void restoreEntities(){<commit_msg>BlockRegen Changes<commit_after>package au.com.mineauz.minigames.blockRecorder;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.Comparator;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.*;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Animals;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.minecart.HopperMinecart;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.block.BlockSpreadEvent;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.vehicle.VehicleCreateEvent;
import org.bukkit.event.vehicle.VehicleDestroyEvent;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;

import com.google.common.collect.Lists;

import au.com.mineauz.minigames.MinigamePlayer;
import au.com.mineauz.minigames.MinigameUtils;
import au.com.mineauz.minigames.Minigames;
import au.com.mineauz.minigames.menu.Callback;
import au.com.mineauz.minigames.minigame.Minigame;
import au.com.mineauz.minigames.minigame.MinigameState;

public class RecorderData implements Listener{
	private static Minigames plugin;
	
	private Minigame minigame;
	private boolean whitelistMode = false;
	private List<Material> wbBlocks = new ArrayList<Material>();
	private boolean hasCreatedRegenBlocks = false;
	
	private Map<String, BlockData> blockdata;
	private Map<Integer, EntityData> entdata;
	
	private static List<Material> physBlocks = new ArrayList<Material>();
	
	static{
		physBlocks.add(Material.TORCH);
		physBlocks.add(Material.SIGN_POST);
		physBlocks.add(Material.WALL_SIGN);
		physBlocks.add(Material.TRIPWIRE);
		physBlocks.add(Material.RAILS);
		physBlocks.add(Material.POWERED_RAIL);
		physBlocks.add(Material.ACTIVATOR_RAIL);
		physBlocks.add(Material.REDSTONE_WIRE);
		physBlocks.add(Material.REDSTONE_TORCH_OFF);
		physBlocks.add(Material.REDSTONE_TORCH_ON);
		physBlocks.add(Material.SAPLING);
        physBlocks.add(Material.RED_ROSE);
		physBlocks.add(Material.YELLOW_FLOWER);
        physBlocks.add(Material.NETHER_WARTS);
        physBlocks.add(Material.YELLOW_FLOWER);
		physBlocks.add(Material.WOOD_PLATE);
		physBlocks.add(Material.STONE_PLATE);
		physBlocks.add(Material.GOLD_PLATE);
		physBlocks.add(Material.IRON_PLATE);
		physBlocks.add(Material.STONE_BUTTON);
		physBlocks.add(Material.WOOD_BUTTON);
		physBlocks.add(Material.LEVER);
		physBlocks.add(Material.LADDER);
		physBlocks.add(Material.IRON_DOOR);
		physBlocks.add(Material.WOODEN_DOOR);
		physBlocks.add(Material.RED_MUSHROOM);
		physBlocks.add(Material.BROWN_MUSHROOM);
		physBlocks.add(Material.DOUBLE_PLANT);
		physBlocks.add(Material.FLOWER_POT);
		physBlocks.add(Material.WATER_LILY);
		physBlocks.add(Material.TRIPWIRE_HOOK);
		physBlocks.add(Material.TRAP_DOOR);
		physBlocks.add(Material.CARPET);
		physBlocks.add(Material.LONG_GRASS);
		physBlocks.add(Material.DEAD_BUSH);
		physBlocks.add(Material.REDSTONE_COMPARATOR_ON);
		physBlocks.add(Material.REDSTONE_COMPARATOR_OFF);
		physBlocks.add(Material.DIODE_BLOCK_OFF);
		physBlocks.add(Material.DIODE_BLOCK_ON);
		physBlocks.add(Material.WATER);
		physBlocks.add(Material.LAVA);
		physBlocks.add(Material.STATIONARY_WATER);
		physBlocks.add(Material.STATIONARY_LAVA);
		physBlocks.add(Material.ANVIL);
		physBlocks.add(Material.DRAGON_EGG);
		physBlocks.add(Material.SKULL);
		physBlocks.add(Material.SNOW);
        physBlocks.add(Material.VINE);
        physBlocks.add(Material.PORTAL);
        physBlocks.add(Material.COCOA);
        physBlocks.add(Material.CARROT);
        physBlocks.add(Material.POTATO);
        physBlocks.add(Material.WALL_BANNER);
    }
	
	public RecorderData(Minigame minigame){
		plugin = Minigames.plugin;
		
		this.minigame = minigame;
		blockdata = new HashMap<String, BlockData>();
		entdata = new HashMap<Integer, EntityData>();
		
//		plugin.getServer().getPluginManager().registerEvents(this, plugin);
	}
	
	public void setWhitelistMode(boolean bool){
		whitelistMode = bool;
	}
	
	public boolean getWhitelistMode(){
		return whitelistMode;
	}
	
	public Callback<Boolean> getWhitelistModeCallback(){
		return new Callback<Boolean>() {

			@Override
			public void setValue(Boolean value) {
				whitelistMode = value;
			}

			@Override
			public Boolean getValue() {
				return whitelistMode;
			}
		};
	}
	
	public void addWBBlock(Material mat){
		wbBlocks.add(mat);
	}
	
	public List<Material> getWBBlocks(){
		return wbBlocks;
	}
	
	public boolean removeWBBlock(Material mat){
		if(wbBlocks.contains(mat)){
			wbBlocks.remove(mat);
			return true;
		}
		return false;
	}
	
	public boolean hasCreatedRegenBlocks(){
		return hasCreatedRegenBlocks;
	}
	
	public void setCreatedRegenBlocks(boolean bool){
		hasCreatedRegenBlocks = bool;
	}
	
	public Minigame getMinigame(){
		return minigame;
	}
	
	public BlockData addBlock(Block block, MinigamePlayer modifier){
		return addBlock(block.getState(), modifier);
	}
	
	public BlockData addBlock(BlockState block, MinigamePlayer modifier){
		BlockData bdata = new BlockData(block, modifier);
		String sloc = String.valueOf(bdata.getLocation().getBlockX()) + ":" + bdata.getLocation().getBlockY() + ":" + bdata.getLocation().getBlockZ();
		if(!blockdata.containsKey(sloc)){
		    if(block instanceof InventoryHolder){
                InventoryHolder inv = (InventoryHolder) block;
                if(inv instanceof DoubleChest){
                    Location left = ((DoubleChest) inv).getLeftSide().getInventory().getLocation().clone();
                    Location right = ((DoubleChest) inv).getRightSide().getInventory().getLocation().clone();
                    if (bdata.getLocation() == left){
                        addInventory(bdata,((DoubleChest) inv).getLeftSide());
                        if(minigame.isRandomizeChests())
                            bdata.randomizeContents(minigame.getMinChestRandom(), minigame.getMaxChestRandom());
                    }
                    BlockData secondChest =  addBlock(right.getBlock(),null);
                    if(secondChest.getItems() == null){
                        addInventory(secondChest,((DoubleChest) inv).getRightSide());
                        if(minigame.isRandomizeChests())
                            secondChest.randomizeContents(minigame.getMinChestRandom(), minigame.getMaxChestRandom());
                    }
                else if(inv instanceof Chest){
                        addInventory(bdata,inv);
                        if(minigame.isRandomizeChests())
                            bdata.randomizeContents(minigame.getMinChestRandom(), minigame.getMaxChestRandom());
                    }
                }else{
                    addInventory(bdata,inv);
                }
            }
			else if(block.getType() == Material.FLOWER_POT){
				bdata.setSpecialData("contents", block.getData());
			}
			
			blockdata.put(sloc, bdata);
			return bdata;
		}
		else{
			if(block.getType() != Material.CHEST || !blockdata.get(sloc).hasRandomized())
				blockdata.get(sloc).setModifier(modifier);
			return blockdata.get(sloc);
		}
	}

	public void addInventory(BlockData bdata, InventoryHolder ih){
        List<ItemStack> items = new ArrayList<>();

        for(ItemStack item: ih.getInventory()){
            items.add(item.clone());
        }
        ItemStack[] inventory = new ItemStack[items.size()];
        items.toArray(inventory);
        bdata.setItems(inventory);
    }

	
	public void addEntity(Entity ent, MinigamePlayer player, boolean created){
		EntityData edata = new EntityData(ent, player, created);
		entdata.put(ent.getEntityId(), edata);
	}
	
	public boolean hasEntity(Entity ent){
        return entdata.containsKey(ent.getEntityId());
    }
	
	public boolean hasBlock(Block block){
		String sloc = String.valueOf(block.getLocation().getBlockX()) + ":" + block.getLocation().getBlockY() + ":" + block.getLocation().getBlockZ();
        return blockdata.containsKey(sloc);
    }
	
	public void restoreAll(MinigamePlayer modifier) {
		if (!blockdata.isEmpty()) {
			restoreBlocks(modifier);
		}
		
		if (!entdata.isEmpty()) {
			restoreEntities(modifier);
		}
	}
	
	public void restoreBlocks(){
//		saveAllBlockData();
		restoreBlocks(null);
	}
	
	public void restoreEntities(){
{'fraction_non_alphanumeric': 0.12528344671201813, 'fraction_numerical': 0.0005153576582148011, 'mean_word_length': 4.214995968825584, 'pattern_counts': {'":': 8, '<': 31, '<?xml version=': 0, '>': 28, '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': '4673246', 'n_tokens_mistral': 7179, 'n_tokens_neox': 6327, 'n_words': 960}