<commit_before>package com.untamedears.PrisonPearl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.Callable;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;

public class PrisonPearlPlugin extends JavaPlugin implements Listener, CommandExecutor {
	private DamageLogManager damageman;
	private PrisonPearlManager pearlman;
	private PrisonPearlStorage pearls;
	private SummonManager summonman;

	public void onEnable() {
		getConfig().options().copyDefaults(true);
		saveConfig();
		
		pearls = new PrisonPearlStorage();
		load(pearls, getPrisonPearlsFile());
		
		damageman = new DamageLogManager(this);
		pearlman = new PrisonPearlManager(this, pearls);
		summonman = new SummonManager(this, pearls);
		load(summonman, getSummonFile());
		
		getServer().getPluginManager().registerEvents(this, this);
		getCommand("pplocate").setExecutor(this);
		getCommand("pplocateany").setExecutor(this);
		getCommand("ppfree").setExecutor(this);
		getCommand("ppfreeany").setExecutor(this);
		getCommand("ppsummon").setExecutor(this);
		getCommand("ppreturn").setExecutor(this);
		if (getConfig().getBoolean("ppkill_enabled"))
			getCommand("ppkill").setExecutor(this);

		// shamelessly swiped from bookworm, not sure why there isn't a Bukkit API for this
		// this causes items to be stacked by their durability value
		try {
			Method method = net.minecraft.server.Item.class.getDeclaredMethod("a", boolean.class);
			if (method.getReturnType() == net.minecraft.server.Item.class) {
				method.setAccessible(true);
				method.invoke(net.minecraft.server.Item.ENDER_PEARL, true);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void onDisable() {
		save(pearls, getPrisonPearlsFile());
		save(summonman, getSummonFile());
	}
	
	private static void load(SaveLoad obj, File file) {
		try {
			obj.load(file);
		} catch (FileNotFoundException e) {
			System.out.println(file.getName() + " not exist, creating.");

			try {
				obj.save(file);
			} catch (IOException e2) {
				throw new RuntimeException("Failed to create " + file.getAbsolutePath(), e2);
			}
		} catch (IOException e) {
			throw new RuntimeException("Failed to load prison pearls from " + file.getAbsolutePath(), e);
		}
	}
	
	private static void save(SaveLoad obj, File file) {
		try {
			if (file.exists())
				file.renameTo(new File(file.getAbsolutePath() + ".bak"));
			obj.save(file);
		} catch (IOException e) {
			throw new RuntimeException("Failed to save prison pearls to " + file.getAbsolutePath(), e);
		}
	}

	private File getPrisonPearlsFile() {
		return new File(getDataFolder(), "prisonpearls.txt");
	}
	
	private File getSummonFile() {
		return new File(getDataFolder(), "summons.txt");
	}
	
	// go through player spawn logic in playerSpawn, teleport them as needed
	@EventHandler(priority=EventPriority.HIGHEST)
	public void onPlayerJoin(PlayerJoinEvent event) {
		final Player player = event.getPlayer();
		if (player.isDead())
			return;
		
		final Location newloc = playerSpawn(player, player.getLocation());
		if (newloc != null) {
			// under very specific situations it seems like teleport directly in onPlayerJoin causes duplicate entities
			Bukkit.getScheduler().callSyncMethod(this, new Callable<Void>() {
				public Void call() {
					player.teleport(newloc);
					return null;
				}
			});
			
		}
	}
	
	// run player spawn logic in playerSpawn
	@EventHandler(priority=EventPriority.HIGHEST)
	public void onPlayerRespawn(PlayerRespawnEvent event) {
		Location newloc = playerSpawn(event.getPlayer(), event.getRespawnLocation());
		if (newloc != null)
			event.setRespawnLocation(newloc);
	}
	
	// tp people in and out of the prison world
	private Location playerSpawn(Player player, Location spawnloc) {
		World respawn = Bukkit.getWorld(getConfig().getString("respawn_world"));
		World prison = Bukkit.getWorld(getConfig().getString("prison_world"));
		Location newloc=null;
		
		if (pearls.isImprisoned(player)) { // if player is imprisoned
			if (!summonman.isSummoned(player)) { // and not summoned
				if (spawnloc.getWorld() != prison) // make sure he spawns in the prison world
					newloc = prison.getSpawnLocation();
				
				for (String line : getConfig().getStringList("prison_motd")) // give him prison_motd
					player.sendMessage(line);
			}
		} else if (spawnloc.getWorld() == prison) { // not imprisoned, but spawning in prison?
			newloc = respawn.getSpawnLocation(); // he must've been free'd while offline, change location to spawn
			player.sendMessage("While away, you were freed!");
		}		
		
		return newloc;
	}	
	
	// Imprison people upon death
	@EventHandler(priority=EventPriority.HIGHEST)
	public void onEntityDeath(EntityDeathEvent event) {
		if (!(event.getEntity() instanceof Player))
			return;
		
		Player player = (Player)event.getEntity();
		if (getConfig().getBoolean("prisonerstealing_enabled") == false && pearls.isImprisoned(player)) // bail if we can't steal prisoners and the guy is already imprisoned
			return;
		
		List<Player> damagers = damageman.getDamagers(player); // get all the players who helped kill this guy<commit_msg>Don't allow imprisonment to occur while in the prison world, even if prisonerstealing is enabled<commit_after>package com.untamedears.PrisonPearl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.Callable;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;

public class PrisonPearlPlugin extends JavaPlugin implements Listener, CommandExecutor {
	private DamageLogManager damageman;
	private PrisonPearlManager pearlman;
	private PrisonPearlStorage pearls;
	private SummonManager summonman;

	public void onEnable() {
		getConfig().options().copyDefaults(true);
		saveConfig();
		
		pearls = new PrisonPearlStorage();
		load(pearls, getPrisonPearlsFile());
		
		damageman = new DamageLogManager(this);
		pearlman = new PrisonPearlManager(this, pearls);
		summonman = new SummonManager(this, pearls);
		load(summonman, getSummonFile());
		
		getServer().getPluginManager().registerEvents(this, this);
		getCommand("pplocate").setExecutor(this);
		getCommand("pplocateany").setExecutor(this);
		getCommand("ppfree").setExecutor(this);
		getCommand("ppfreeany").setExecutor(this);
		getCommand("ppsummon").setExecutor(this);
		getCommand("ppreturn").setExecutor(this);
		if (getConfig().getBoolean("ppkill_enabled"))
			getCommand("ppkill").setExecutor(this);

		// shamelessly swiped from bookworm, not sure why there isn't a Bukkit API for this
		// this causes items to be stacked by their durability value
		try {
			Method method = net.minecraft.server.Item.class.getDeclaredMethod("a", boolean.class);
			if (method.getReturnType() == net.minecraft.server.Item.class) {
				method.setAccessible(true);
				method.invoke(net.minecraft.server.Item.ENDER_PEARL, true);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void onDisable() {
		save(pearls, getPrisonPearlsFile());
		save(summonman, getSummonFile());
	}
	
	private static void load(SaveLoad obj, File file) {
		try {
			obj.load(file);
		} catch (FileNotFoundException e) {
			System.out.println(file.getName() + " not exist, creating.");

			try {
				obj.save(file);
			} catch (IOException e2) {
				throw new RuntimeException("Failed to create " + file.getAbsolutePath(), e2);
			}
		} catch (IOException e) {
			throw new RuntimeException("Failed to load prison pearls from " + file.getAbsolutePath(), e);
		}
	}
	
	private static void save(SaveLoad obj, File file) {
		try {
			if (file.exists())
				file.renameTo(new File(file.getAbsolutePath() + ".bak"));
			obj.save(file);
		} catch (IOException e) {
			throw new RuntimeException("Failed to save prison pearls to " + file.getAbsolutePath(), e);
		}
	}

	private File getPrisonPearlsFile() {
		return new File(getDataFolder(), "prisonpearls.txt");
	}
	
	private File getSummonFile() {
		return new File(getDataFolder(), "summons.txt");
	}
	
	// go through player spawn logic in playerSpawn, teleport them as needed
	@EventHandler(priority=EventPriority.HIGHEST)
	public void onPlayerJoin(PlayerJoinEvent event) {
		final Player player = event.getPlayer();
		if (player.isDead())
			return;
		
		final Location newloc = playerSpawn(player, player.getLocation());
		if (newloc != null) {
			// under very specific situations it seems like teleport directly in onPlayerJoin causes duplicate entities
			Bukkit.getScheduler().callSyncMethod(this, new Callable<Void>() {
				public Void call() {
					player.teleport(newloc);
					return null;
				}
			});
			
		}
	}
	
	// run player spawn logic in playerSpawn
	@EventHandler(priority=EventPriority.HIGHEST)
	public void onPlayerRespawn(PlayerRespawnEvent event) {
		Location newloc = playerSpawn(event.getPlayer(), event.getRespawnLocation());
		if (newloc != null)
			event.setRespawnLocation(newloc);
	}
	
	// tp people in and out of the prison world
	private Location playerSpawn(Player player, Location spawnloc) {
		World respawn = Bukkit.getWorld(getConfig().getString("respawn_world"));
		World prison = Bukkit.getWorld(getConfig().getString("prison_world"));
		Location newloc=null;
		
		if (pearls.isImprisoned(player)) { // if player is imprisoned
			if (!summonman.isSummoned(player)) { // and not summoned
				if (spawnloc.getWorld() != prison) // make sure he spawns in the prison world
					newloc = prison.getSpawnLocation();
				
				for (String line : getConfig().getStringList("prison_motd")) // give him prison_motd
					player.sendMessage(line);
			}
		} else if (spawnloc.getWorld() == prison) { // not imprisoned, but spawning in prison?
			newloc = respawn.getSpawnLocation(); // he must've been free'd while offline, change location to spawn
			player.sendMessage("While away, you were freed!");
		}		
		
		return newloc;
	}	
	
	// Imprison people upon death
	@EventHandler(priority=EventPriority.HIGHEST)
	public void onEntityDeath(EntityDeathEvent event) {
		if (!(event.getEntity() instanceof Player))
			return;
		
		Player player = (Player)event.getEntity();
		World prison = Bukkit.getWorld(getConfig().getString("prison_world"));
		
		if (player.getLocation().getWorld() == prison) // don't allow people to imprison other people while in the prison world
			return;
		
		if (getConfig().getBoolean("prisonerstealing_enabled") == false && pearls.isImprisoned(player)) // bail if we can't steal prisoners and the guy is already imprisoned
			return;
		
		List<Player> damagers = damageman.getDamagers(player); // get all the players who helped kill this guy
{'fraction_non_alphanumeric': 0.1175977887595276, 'fraction_numerical': 0.0003350364352123293, 'mean_word_length': 4.658767772511848, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '5996487', 'n_tokens_mistral': 4088, 'n_tokens_neox': 3632, 'n_words': 902}