public class CreativeEntityRemover {
	private CustomPlugin plugin;

	public CreativeEntityRemover(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		if (plugin.detectedServer().equals("destruction")) {
			Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
				@Override
				public void run() {
					List<Entity> entList = plugin.getServer().getWorld("Destruction").getEntities();

					for(Entity current : entList) {
						if (!(current instanceof Player || current instanceof ItemFrame)) {
							current.remove();
						}
					}
				}
			}, 20*5, 20*60*5);
		}
		if (plugin.detectedServer().equals("creative")) {
			Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
				@Override
				public void run() {
					List<Entity> entList = plugin.getServer().getWorld("Build").getEntities();

					for(Entity current : entList) {
						if (!(current instanceof Player || current instanceof ItemFrame)) {
							current.remove();
						}
					}
				}
			}, 20*5, 20*60*5);
		}
		log("Enabled");
	}

	public void log(String info) {
		plugin.getLogger().info("<CreativeEntityRemover> " + info);
	}
} public class PlotMeOverride implements Listener {
	private CustomPlugin plugin;

	int wallLength = 22;

	public PlotMeOverride(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		plugin.getServer().getPluginManager().registerEvents(this, plugin);
		log("Enabled");
	}

	private void attemptConnection(Player player) {
		// Define whether he can make a link of 4 plots
		String name = player.getName();
		int x;
		int z;
		Plot in = PlotManager.getPlotById(player);
		try {
			x = PlotManager.getIdX(PlotManager.getPlotId(player.getLocation()));
			z = PlotManager.getIdZ(PlotManager.getPlotId(player.getLocation()));
		} catch (Exception e) {
			return;
		}
		boolean isIn;
		if (in == null) {
			isIn = false;
		} else {
			if (in.owner.equals(name)) {
				isIn = true;
			} else {
				return;
			}
		}
		boolean doneAnything = false;
		if (!isIn) {
			regenWalls(x, z);
			return;
		}
		Plot a = getPlot((x - 1) + ";" + (z + 1));
		Plot b = getPlot(x + ";" + (z + 1));
		Plot c = getPlot((x + 1) + ";" + (z + 1));
		Plot d = getPlot((x + 1) + ";" + z);
		Plot e = getPlot((x + 1) + ";" + (z - 1));
		Plot f = getPlot(x + ";" + (z - 1));
		Plot g = getPlot((x - 1) + ";" + (z - 1));
		Plot h = getPlot((x - 1) + ";" + z);
		if (a != null && h != null && b != null)
			if (a.owner.equals(name) && h.owner.equals(name)
					&& b.owner.equals(name)) {
				openWalls(1, in, player.getName());
				doneAnything = true;
			} else {
				removeMode(in, 1);
			}
		if (c != null && d != null && b != null)
			if (c.owner.equals(name) && d.owner.equals(name)
					&& b.owner.equals(name)) {
				openWalls(2, in, player.getName());
				doneAnything = true;
			} else {
				removeMode(in, 2);
			}
		if (e != null && f != null && d != null)
			if (e.owner.equals(name) && f.owner.equals(name)
					&& d.owner.equals(name)) {
				openWalls(3, in, player.getName());
				doneAnything = true;
			} else {
				removeMode(in, 3);
			}
		if (g != null && h != null && f != null)
			if (g.owner.equals(name) && h.owner.equals(name)
					&& f.owner.equals(name)) {
				openWalls(4, in, player.getName());
				doneAnything = true;
			} else {
				removeMode(in, 4);
			}
		if (doneAnything)
			return;
		// If so, run another method, else default here
		if (b != null)
			if (b.owner.equals(name)) {
				openWalls(5, in, player.getName());
			} else {
				removeMode(in, 5);
			}
		if (d != null)
			if (d.owner.equals(name)) {
				openWalls(6, in, player.getName());
			} else {
				removeMode(in, 6);
			}
		if (f != null)
			if (f.owner.equals(name)) {
				openWalls(7, in, player.getName());
			} else {
				removeMode(in, 7);
			}
		if (h != null)
			if (h.owner.equals(name)) {
				openWalls(8, in, player.getName());
			} else {
				removeMode(in, 8);
			}
	}

	private void openWalls(int mode, Plot plot, String player) {
		// log("Mode Detected: " + mode);
		World w = Bukkit.getWorld("Build");
		if (mode == 1 && !hasMode(plot, 1)) {
			Location loc = new Location(w, PlotManager.bottomX(plot.id, w), 64,
					PlotManager.topZ(plot.id, w));
			loc.add(-3, 0, 3);
			buildWithCenter(loc, player);
		}
		if (mode == 2 && !hasMode(plot, 2)) {
			Location loc = new Location(w, PlotManager.topX(plot.id, w), 64,
					PlotManager.topZ(plot.id, w));
			loc.add(3, 0, 3);
			buildWithCenter(loc, player);
		}
		if (mode == 3 && !hasMode(plot, 3)) {
			Location loc = new Location(w, PlotManager.topX(plot.id, w), 64,
					PlotManager.bottomZ(plot.id, w));
			loc.add(3, 0, -3);
			buildWithCenter(loc, player);
		}
		if (mode == 4 && !hasMode(plot, 4)) {
			Location loc = new Location(w, PlotManager.bottomX(plot.id, w), 64,
					PlotManager.bottomZ(plot.id, w));
			loc.add(-3, 0, -3);
			buildWithCenter(loc, player);
		}
		
		if (mode == 5 && !hasMode(plot, 5)) {
			Location loc = new Location(w, midNum(
					PlotManager.bottomX(plot.id, w),
					PlotManager.topX(plot.id, w)), 64, PlotManager.topZ(
					plot.id, w));
			loc.add(0, 0, 3);
			buildWithCenterHoriz(loc);
		}
		if (mode == 6 && !hasMode(plot, 6)) {
			Location loc = new Location(w, PlotManager.topX(plot.id, w), 64,
					midNum(PlotManager.bottomZ(plot.id, w),
							PlotManager.topZ(plot.id, w)));
			loc.add(3, 0, 0);
			buildWithCenterVert(loc);
		}
		if (mode == 7 && !hasMode(plot, 7)) {
			Location loc = new Location(w, midNum(
					PlotManager.bottomX(plot.id, w),
					PlotManager.topX(plot.id, w)), 64, PlotManager.bottomZ(
					plot.id, w));
			loc.add(0, 0, -3);
			buildWithCenterHoriz(loc);
		}
		if (mode == 8 && !hasMode(plot, 8)) {
			Location loc = new Location(w, PlotManager.bottomX(plot.id, w), 64,
					midNum(PlotManager.bottomZ(plot.id, w),
							PlotManager.topZ(plot.id, w)));
			loc.add(-3, 0, 0);
			buildWithCenterVert(loc);
		}
		addMode(plot, mode);
	}
	
	@SuppressWarnings("deprecation")
	private boolean hasMode(Plot plot, int mode) {
		Block base = PlotManager.getBottom(Bukkit.getWorld("Build"), plot).getBlock();
		if (base.getLocation().clone().add(mode, 0, 0).getBlock().getData() == 1)
			return true;
		return false;
	}
	
	@SuppressWarnings("deprecation")
	private void addMode(Plot plot, int mode) {
		Block base = PlotManager.getBottom(Bukkit.getWorld("Build"), plot).getBlock();
		base.getLocation().clone().add(mode, 0, 0).getBlock().setData((byte) 1);
	}
	
	@SuppressWarnings("deprecation")
	private void removeMode(Plot plot, int mode) {
		Block base = PlotManager.getBottom(Bukkit.getWorld("Build"), plot).getBlock();
		base.getLocation().clone().add(mode, 0, 0).getBlock().setData((byte) 0);
	}

	private int midNum(int a, int b) {
		return (a + b) / 2;
	}

	private void buildWithCenter(Location loc, String player) {
		int x = loc.getBlockX();
		int y = loc.getBlockY();
		int z = loc.getBlockZ();
		for (int i = 0; i < wallLength + 2; i++) {
			place(2, x - 1, y, z);
			place(2, x, y, z);
			place(2, x + 1, y, z);
			place(2, x + 2, y, z);
			place(2, x - 2, y, z);
			place(0, x + 2, y + 1, z);
			place(0, x - 2, y + 1, z);
			z++;
		}
		Plot plot = PlotManager.getPlotById(new Location(Bukkit
				.getWorld("Build"), x + 10, y, z + 10));
		Plot plot2 = PlotManager.getPlotById(new Location(Bukkit
				.getWorld("Build"), x - 10, y, z + 10));
		if (!(plot != null && plot.owner.equals(player))
				|| !(plot2 != null && plot2.owner.equals(player))) {
			place(44, 7, x - 2, y + 1, z - 1);
			place(44, 7, x - 1, y + 1, z - 1);
			place(44, 7, x, y + 1, z - 1);
			place(44, 7, x + 1, y + 1, z - 1);
			place(44, 7, x + 2, y + 1, z - 1);
		}
		x = loc.getBlockX();
		z = loc.getBlockZ();
		for (int i = 0; i < wallLength + 2; i++) {
			place(2, x - 1, y, z);
			place(2, x, y, z);
			place(2, x + 1, y, z);
			place(2, x + 2, y, z);
			place(2, x - 2, y, z);
			place(0, x + 2, y + 1, z);
			place(0, x - 2, y + 1, z);
			z--;
		}
		plot = PlotManager.getPlotById(new Location(Bukkit.getWorld("Build"),
				x + 10, y, z - 10));
		plot2 = PlotManager.getPlotById(new Location(Bukkit.getWorld("Build"),
				x - 10, y, z - 10));
		if (!(plot != null && plot.owner.equals(player))
				|| !(plot2 != null && plot2.owner.equals(player))) {
			place(44, 7, x - 2, y + 1, z + 1);
			place(44, 7, x - 1, y + 1, z + 1);
			place(44, 7, x, y + 1, z + 1);
			place(44, 7, x + 1, y + 1, z + 1);
			place(44, 7, x + 2, y + 1, z + 1);
		}
		x = loc.getBlockX();
		z = loc.getBlockZ();
		for (int i = 0; i < wallLength + 2; i++) {
			place(2, x, y, z - 1);
			place(2, x, y, z);
			place(2, x, y, z + 1);
			place(2, x, y, z + 2);
			place(2, x, y, z - 2);
			place(0, x, y + 1, z + 2);
			place(0, x, y + 1, z - 2);
			x++;
		}
		plot = PlotManager.getPlotById(new Location(Bukkit.getWorld("Build"),
				x + 10, y, z + 10));
		plot2 = PlotManager.getPlotById(new Location(Bukkit.getWorld("Build"),
				x + 10, y, z - 10));
		if (!(plot != null && plot.owner.equals(player))
				|| !(plot2 != null && plot2.owner.equals(player))) {
			place(44, 7, x - 1, y + 1, z - 2);
			place(44, 7, x - 1, y + 1, z - 1);
			place(44, 7, x - 1, y + 1, z);
			place(44, 7, x - 1, y + 1, z + 1);
			place(44, 7, x - 1, y + 1, z + 2);
		}
		x = loc.getBlockX();
		z = loc.getBlockZ();
		for (int i = 0; i < wallLength + 2; i++) {
			place(2, x, y, z - 1);
			place(2, x, y, z);
			place(2, x, y, z + 1);
			place(2, x, y, z + 2);
			place(2, x, y, z - 2);
			place(0, x, y + 1, z + 2);
			place(0, x, y + 1, z - 2);
			x--;
		}
		plot = PlotManager.getPlotById(new Location(Bukkit.getWorld("Build"),
				x - 10, y, z + 10));
		plot2 = PlotManager.getPlotById(new Location(Bukkit.getWorld("Build"),
				x - 10, y, z - 10));
		if (!(plot != null && plot.owner.equals(player))
				|| !(plot2 != null && plot2.owner.equals(player))) {
			place(44, 7, x + 1, y + 1, z - 2);
			place(44, 7, x + 1, y + 1, z - 1);
			place(44, 7, x + 1, y + 1, z);
			place(44, 7, x + 1, y + 1, z + 1);
			place(44, 7, x + 1, y + 1, z + 2);
		}
		x = loc.getBlockX();
		z = loc.getBlockZ();

	}

	private void buildWithCenterHoriz(Location loc) {
		int x = loc.getBlockX();
		int x2 = loc.getBlockX();
		int y = loc.getBlockY();
		int z = loc.getBlockZ();
		for (int i = 0; i < wallLength / 2; i++) {
			place(0, x, y + 1, z - 2);
			place(2, x, y, z - 2);
			place(2, x, y, z - 1);
			place(2, x, y, z);
			place(2, x, y, z + 1);
			place(2, x, y, z + 2);
			place(0, x, y + 1, z + 2);

			place(0, x2, y + 1, z - 2);
			place(2, x2, y, z - 2);
			place(2, x2, y, z - 1);
			place(2, x2, y, z);
			place(2, x2, y, z + 1);
			place(2, x2, y, z + 2);
			place(0, x2, y + 1, z + 2);
			x++;
			x2--;
		}
		if (x > 0) {
			x++;
			x2++;
		}
		place(44, 7, x - 1, y + 1, z - 2);
		place(44, 7, x - 1, y + 1, z - 1);
		place(44, 7, x - 1, y + 1, z);
		place(44, 7, x - 1, y + 1, z + 1);
		place(44, 7, x - 1, y + 1, z + 2);

		place(44, 7, x2, y + 1, z - 2);
		place(44, 7, x2, y + 1, z - 1);
		place(44, 7, x2, y + 1, z);
		place(44, 7, x2, y + 1, z + 1);
		place(44, 7, x2, y + 1, z + 2);
	}

	private void buildWithCenterVert(Location loc) {
		int x = loc.getBlockX();
		int y = loc.getBlockY();
		int z = loc.getBlockZ();
		int z2 = loc.getBlockZ();
		for (int i = 0; i < wallLength / 2; i++) {
			place(0, x - 2, y + 1, z);
			place(2, x - 2, y, z);
			place(2, x - 1, y, z);
			place(2, x, y, z);
			place(2, x + 1, y, z);
			place(2, x + 2, y, z);
			place(0, x + 2, y + 1, z);

			place(0, x - 2, y + 1, z2);
			place(2, x - 2, y, z2);
			place(2, x - 1, y, z2);
			place(2, x, y, z2);
			place(2, x + 1, y, z2);
			place(2, x + 2, y, z2);
			place(0, x + 2, y + 1, z2);
			z++;
			z2--;
		}
		if (z > 0) {
			z++;
			z2++;
		}
		place(44, 7, x - 2, y + 1, z - 1);
		place(44, 7, x - 1, y + 1, z - 1);
		place(44, 7, x, y + 1, z - 1);
		place(44, 7, x + 1, y + 1, z - 1);
		place(44, 7, x + 2, y + 1, z - 1);

		place(44, 7, x - 2, y + 1, z2);
		place(44, 7, x - 1, y + 1, z2);
		place(44, 7, x, y + 1, z2);
		place(44, 7, x + 1, y + 1, z2);
		place(44, 7, x + 2, y + 1, z2);
	}

	@SuppressWarnings("deprecation")
	private static void setBlock(int id, int x, int y, int z) {
		try {
			Bukkit.getWorld("Build").getBlockAt(x, y, z).setTypeId(id);
		} catch (Exception e) {}
	}

	@SuppressWarnings("deprecation")
	private static void place(int id, int data, int x, int y, int z) {
		Block b = Bukkit.getWorld("Build").getBlockAt(x, y, z);
		int type = b.getTypeId();
		if (type == 0 || type == 1 || type == 56 || (type == 44 && b.getData() == (byte) 7) || type == 2 || type == 3)
			setBlock(id, x, y, z);
		try {
			Bukkit.getWorld("Build").getBlockAt(x, y, z).setData((byte) data);
		} catch (Exception e) {}
	}

	@SuppressWarnings("deprecation")
	private static void place(int id, int x, int y, int z) {
		Block b = Bukkit.getWorld("Build").getBlockAt(x, y, z);
		int type = b.getTypeId();
		if (type != id)
			if (type == 0 || type == 1 || type == 56 || (type == 44 && b.getData() == (byte) 7) || type == 2 || type == 3)
				setBlock(id, x, y, z);
	}
	
	@SuppressWarnings("deprecation")
	private static void dplace(int id, int data, int x, int y, int z) {
		setBlock(id, x, y, z);
		try {
			Bukkit.getWorld("Build").getBlockAt(x, y, z).setData((byte) data);
		} catch (Exception e) {}
	}

	@SuppressWarnings("deprecation")
	private static void dplace(int id, int x, int y, int z) {
		int type = Bukkit.getWorld("Build").getBlockAt(x, y, z).getTypeId();
		if (type != id) {
			setBlock(id, x, y, z);
		}
	}
	
	private static void regenWalls(int plotx, int plotz) {
		Location bottomPlot = PlotManager.getPlotBottomLoc(
				Bukkit.getWorld("Build"), plotx + ";" + plotz);
		Location topPlot = PlotManager.getPlotTopLoc(Bukkit.getWorld("Build"),
				plotx + ";" + plotz);
		int minx = bottomPlot.getBlockX() - 1;
		int minz = bottomPlot.getBlockZ() - 1;
		int maxx = topPlot.getBlockX() + 1;
		int maxz = topPlot.getBlockZ() + 1;

		// Layers around the plot

		for (int i = minx; i < maxx; i++) {
			dplace(1, i, 64, minz);
			dplace(1, i, 64, maxz);
			fullResetStepPillar(i, minz);
			fullResetStepPillar(i, maxz);
		}
		for (int i = minz; i < maxz; i++) {
			dplace(1, minx, 64, i);
			dplace(1, maxx, 64, i);
			fullResetStepPillar(minx, i);
			fullResetStepPillar(minx, i);
		}
		minx--;
		minz--;
		maxx++;
		maxz++;
		for (int i = minx; i < maxx; i++) {
			dplace(1, i, 64, minz);
			dplace(1, i, 64, maxz);
			fullResetPillar(i, minz);
			fullResetPillar(i, maxz);
		}
		for (int i = minz; i < maxz; i++) {
			dplace(56, minx, 64, i);
			dplace(56, maxx, 64, i);
			fullResetPillar(minx, i);
			fullResetPillar(maxx, i);
		}
		minx--;
		minz--;
		maxx++;
		maxz++;
		for (int i = minx; i < maxx; i++) {
			dplace(1, i, 64, minz);
			dplace(1, i, 64, maxz);
			fullResetPillar(i, minz);
			fullResetPillar(i, maxz);
		}
		for (int i = minz; i < maxz; i++) {
			dplace(1, minx, 64, i);
			dplace(1, maxx, 64, i);
			fullResetPillar(minx, i);
			fullResetPillar(maxx, i);
		}
		minx--;
		minz--;
		maxx++;
		maxz++;
		for (int i = minx; i < maxx; i++) {
			dplace(1, i, 64, minz);
			dplace(1, i, 64, maxz);
			fullResetPillar(i, minz);
			fullResetPillar(i, maxz);
		}
		for (int i = minz; i < maxz; i++) {
			dplace(56, minx, 64, i);
			dplace(56, maxx, 64, i);
			fullResetPillar(minx, i);
			fullResetPillar(maxx, i);
		}
		minx--;
		minz--;
		maxx++;
		maxz++;
		for (int i = minx; i < maxx; i++) {
			dplace(1, i, 64, minz);
			dplace(1, i, 64, maxz);
			fullResetStepPillar(i, minz);
			fullResetStepPillar(i, maxz);
		}
		for (int i = minz; i < maxz; i++) {
			dplace(1, minx, 64, i);
			dplace(1, maxx, 64, i);
			fullResetStepPillar(minx, i);
			fullResetStepPillar(maxx, i);
		}
		// the stair blocks
		minx = bottomPlot.getBlockX() - 1;
		minz = bottomPlot.getBlockZ() - 1;
		maxx = topPlot.getBlockX() + 1;
		maxz = topPlot.getBlockZ() + 1;
		for (int i = minx; i < maxx; i++) {
			dplace(44, 7, i, 65, minz);
			dplace(44, 7, i, 65, maxz);
			dplace(44, 7, i, 65, minz - 4);
			dplace(44, 7, i, 65, maxz + 4);
		}
		for (int i = minz; i < maxz; i++) {
			dplace(44, 7, minx, 65, i);
			dplace(44, 7, maxx, 65, i);
			dplace(44, 7, minx - 4, 65, i);
			dplace(44, 7, maxx + 4, 65, i);
		}
		minx = bottomPlot.getBlockX() - 1;
		minz = bottomPlot.getBlockZ() - 1;
		maxx = topPlot.getBlockX() + 1;
		maxz = topPlot.getBlockZ() + 1;

		// Possible blocks in the pathway cleared encase its not there.

		dplace(0, minx - 1, 65, minz);
		dplace(0, minx - 2, 65, minz);
		dplace(0, minx - 3, 65, minz);
		dplace(0, minx, 65, minz - 1);
		dplace(0, minx, 65, minz - 2);
		dplace(0, minx, 65, minz - 3);
		dplace(44, 7, minx, 65, minz);

		dplace(0, maxx + 1, 65, maxz);
		dplace(0, maxx + 2, 65, maxz);
		dplace(0, maxx + 3, 65, maxz);
		dplace(0, maxx, 65, maxz + 1);
		dplace(0, maxx, 65, maxz + 2);
		dplace(0, maxx, 65, maxz + 3);
		dplace(44, 7, maxx, 65, maxz);

		dplace(0, minx - 1, 65, maxz);
		dplace(0, minx - 2, 65, maxz);
		dplace(0, minx - 3, 65, maxz);
		dplace(0, minx, 65, maxz + 1);
		dplace(0, minx, 65, maxz + 2);
		dplace(0, minx, 65, maxz + 3);
		dplace(44, 7, minx, 65, maxz);

		dplace(0, maxx + 1, 65, minz);
		dplace(0, maxx + 2, 65, minz);
		dplace(0, maxx + 3, 65, minz);
		dplace(0, maxx, 65, minz - 1);
		dplace(0, maxx, 65, minz - 2);
		dplace(0, maxx, 65, minz - 3);
		dplace(44, 7, maxx, 65, minz);

		minx = bottomPlot.getBlockX() - 3;
		minz = bottomPlot.getBlockZ() - 3;
		maxx = topPlot.getBlockX() + 3;
		maxz = topPlot.getBlockZ() + 3;

		setFloorStamp(minx, minz);
		setFloorStamp(minx, maxz);
		setFloorStamp(maxx, minz);
		setFloorStamp(maxx, maxz);

		minx = bottomPlot.getBlockX();
		minz = bottomPlot.getBlockZ();
		maxx = topPlot.getBlockX();
		maxz = topPlot.getBlockZ();

		// Check for open plots to close the walls for.

		Plot a = getPlot((plotx + 1) + ";" + (plotz + 1));
		Plot b = getPlot(plotx + ";" + (plotz + 1));
		Plot c = getPlot((plotx - 1) + ";" + (plotz + 1));
		Plot d = getPlot((plotx - 1) + ";" + plotz);
		Plot e = getPlot((plotx - 1) + ";" + (plotz - 1));
		Plot f = getPlot(plotx + ";" + (plotz - 1));
		Plot g = getPlot((plotx + 1) + ";" + (plotz - 1));
		Plot h = getPlot((plotx + 1) + ";" + plotz);
		if (a != null && b != null)
			if (a.owner.equals(b.owner)) {
				dplace(44, 7, maxx + 1, 65, maxz + 5);
				dplace(44, 7, maxx + 2, 65, maxz + 5);
				dplace(44, 7, maxx + 3, 65, maxz + 5);
				dplace(44, 7, maxx + 4, 65, maxz + 5);
				dplace(44, 7, maxx + 5, 65, maxz + 5);
			}
		if (b != null && c != null)
			if (b.owner.equals(c.owner)) {
				dplace(44, 7, minx - 2, 65, maxz + 5);
				dplace(44, 7, minx - 3, 65, maxz + 5);
				dplace(44, 7, minx - 4, 65, maxz + 5);
				dplace(44, 7, minx - 5, 65, maxz + 5);
			}
		if (c != null && d != null)
			if (c.owner.equals(d.owner)) {
				dplace(44, 7, minx - 5, 65, maxz + 1);
				dplace(44, 7, minx - 5, 65, maxz + 2);
				dplace(44, 7, minx - 5, 65, maxz + 3);
				dplace(44, 7, minx - 5, 65, maxz + 4);
				dplace(44, 7, minx - 5, 65, maxz + 5);
			}
		if (d != null && e != null)
			if (d.owner.equals(e.owner)) {
				dplace(44, 7, minx - 5, 65, minz - 2);
				dplace(44, 7, minx - 5, 65, minz - 3);
				dplace(44, 7, minx - 5, 65, minz - 4);
				dplace(44, 7, minx - 5, 65, minz - 5);
			}
		if (e != null && f != null)
			if (e.owner.equals(f.owner)) {
				dplace(44, 7, minx - 2, 65, minz - 5);
				dplace(44, 7, minx - 3, 65, minz - 5);
				dplace(44, 7, minx - 4, 65, minz - 5);
				dplace(44, 7, minx - 5, 65, minz - 5);
			}
		if (f != null && g != null)
			if (f.owner.equals(g.owner)) {
				dplace(44, 7, maxx + 1, 65, minz - 5);
				dplace(44, 7, maxx + 2, 65, minz - 5);
				dplace(44, 7, maxx + 3, 65, minz - 5);
				dplace(44, 7, maxx + 4, 65, minz - 5);
				dplace(44, 7, maxx + 5, 65, minz - 5);
			}
		if (g != null && h != null)
			if (g.owner.equals(h.owner)) {
				dplace(44, 7, maxx + 5, 65, minz - 2);
				dplace(44, 7, maxx + 5, 65, minz - 3);
				dplace(44, 7, maxx + 5, 65, minz - 4);
				dplace(44, 7, maxx + 5, 65, minz - 5);
			}
		if (h != null && a != null)
			if (h.owner.equals(a.owner)) {
				dplace(44, 7, maxx + 5, 65, maxz + 1);
				dplace(44, 7, maxx + 5, 65, maxz + 2);
				dplace(44, 7, maxx + 5, 65, maxz + 3);
				dplace(44, 7, maxx + 5, 65, maxz + 4);
				dplace(44, 7, maxx + 5, 65, maxz + 5);
			}
	}

	private static void setFloorStamp(int x, int z) {
		for (int tx = x - 2; tx <= x + 2; tx++) {
			for (int tz = z - 2; tz <= z + 2; tz++) {
				dplace(1, tx, 64, tz);
			}
		}
		dplace(56, x, 64, z);
		dplace(56, x + 1, 64, z);
		dplace(56, x - 1, 64, z);
		dplace(56, x, 64, z + 1);
		dplace(56, x, 64, z - 1);
	}

	private static void fullResetPillar(int x, int z) {
		for (int i = 0; i <= 63; i++)
			dplace(3, x, i, z);
		for (int i = 65; i <= 256; i++)
			dplace(0, x, i, z);
	}

	private static void fullResetStepPillar(int x, int z) {
		for (int i = 0; i <= 63; i++)
			dplace(3, x, i, z);
		for (int i = 66; i <= 256; i++)
			dplace(0, x, i, z);
	}

	private boolean inLegalArea(Location loc, Player player) {
		String id = PlotManager.getPlotId(loc);
		String xCheck1 = PlotManager.getPlotId(loc.clone().add(5, 0, 0));
		String xCheck2 = PlotManager.getPlotId(loc.clone().add(-5, 0, 0));
		String yCheck1 = PlotManager.getPlotId(loc.clone().add(0, 0, 5));
		String yCheck2 = PlotManager.getPlotId(loc.clone().add(0, 0, -5));
		// log(xCheck1 + " : " + xCheck2 + " : " + yCheck1 + " : " + yCheck2);
		if (getPlot(id) != null && getPlot(id).isAllowed(player.getName()))
			return true;
		if (player.isOp())
			return true;
		String name = player.getName();
		if (!xCheck1.equals("") && !xCheck2.equals(""))
			if (getPlot(xCheck1) != null && getPlot(xCheck2) != null)
				if (getPlot(xCheck1).isAllowed(name)
						&& getPlot(xCheck2).isAllowed(name))
					return true;
		if (!yCheck1.equals("") && !yCheck2.equals(""))
			if (getPlot(yCheck1) != null && getPlot(yCheck2) != null)
				if (getPlot(yCheck1).isAllowed(name)
						&& getPlot(yCheck2).isAllowed(name))
					return true;
		if (checkCorners(loc, player))
			return true;

		return false;
	}

	private boolean checkCorners(Location loc, Player player) {
		String cor1 = PlotManager.getPlotId(loc.clone().add(5, 0, 5));
		String cor2 = PlotManager.getPlotId(loc.clone().add(-5, 0, 5));
		String cor3 = PlotManager.getPlotId(loc.clone().add(5, 0, 5));
		String cor4 = PlotManager.getPlotId(loc.clone().add(-5, 0, -5));
		// log(cor1 + " : " + cor2 + " : " + cor3 + " : " + cor4);
		String name = player.getName();
		if (!cor1.equals("") && !cor2.equals("") && !cor3.equals("")
				&& !cor4.equals(""))
			if (getPlot(cor1) != null && getPlot(cor2) != null
					&& getPlot(cor3) != null && getPlot(cor4) != null)
				if (getPlot(cor1).isAllowed(name)
						&& getPlot(cor2).isAllowed(name)
						&& getPlot(cor3).isAllowed(name)
						&& getPlot(cor4).isAllowed(name))
					return true;
		return false;
	}

	private static Plot getPlot(String id) {
		return PlotManager.getPlotById(Bukkit.getWorld("Build"), id);
	}

	public static void command(String id) {
		regenWalls(PlotManager.getIdX(id), PlotManager.getIdZ(id));
	}

	@EventHandler(priority = EventPriority.HIGHEST)
	public void onPlayerPlaceBlock(BlockPlaceEvent e) {
		if (e.getPlayer() != null
				&& e.getPlayer().getWorld().getName().equals("Build")) {
			if (e.isCancelled()
					&& inLegalArea(e.getBlock().getLocation(), e.getPlayer()))
				e.setCancelled(false);
		}
	}

	@EventHandler(priority = EventPriority.HIGHEST)
	public void onPlayerBreak(BlockBreakEvent e) {
		if (e.getPlayer() != null
				&& e.getPlayer().getWorld().getName().equals("Build") && !e.getPlayer().getItemInHand().getType().equals(Material.WOOD_AXE) && !e.getPlayer().getItemInHand().getType().equals(Material.COMPASS)) {
			if (e.isCancelled()
					&& inLegalArea(e.getBlock().getLocation(), e.getPlayer()))
				e.setCancelled(false);
		}
	}

	@EventHandler(priority = EventPriority.HIGHEST)
	public void onPlayerInteract(PlayerInteractEvent e) {
		if (e.getClickedBlock() != null
				&& e.getPlayer().getWorld().getName().equals("Build")
				&& !e.getPlayer().getItemInHand().getType().equals(Material.WOOD_AXE) && !e.getPlayer().getItemInHand().getType().equals(Material.COMPASS))
			if (e.isCancelled()
					&& inLegalArea(e.getClickedBlock().getLocation(),
							e.getPlayer()))
				e.setCancelled(false);
	}

	@SuppressWarnings("deprecation")
	@EventHandler
	public void onCommandSent(final PlayerCommandPreprocessEvent e) {
		
		if (e.getMessage().toLowerCase().startsWith("/plot")) {
			if (e.getPlayer().getWorld().getName().equals("Build")) {
				if (!e.getMessage().toLowerCase().startsWith("/plotme"))
					e.setMessage("/plotme" + e.getMessage().substring(5, e.getMessage().length()));
				
				final boolean tp;
				if (e.getMessage().toLowerCase().startsWith("/plotme auto")) {
					tp = true;
				} else {
					tp = false;
				}
				final Location playerLoc = e.getPlayer().getLocation();
				plugin.getServer().getScheduler()
						.scheduleAsyncDelayedTask(plugin, new Runnable() {
							@Override
							public void run() {
								if (tp && e.getPlayer().getLocation() != playerLoc)
									e.getPlayer().teleport(
											e.getPlayer().getLocation().clone()
													.add(0, 0, 5));
								attemptConnection(e.getPlayer());
							}
						}, 5);
				if (e.getMessage().toLowerCase().startsWith("/plotme update")) {
					e.getPlayer().sendMessage(
							ChatColor.BLUE + "[PlotMe] " + ChatColor.WHITE
									+ "Plot updated relative to plots around it.");
					e.setCancelled(true);
				}
				if (e.getMessage().toLowerCase().startsWith("/plotme clear")) {
					if (e.getPlayer().hasPermission("plotme.admin")) {
						e.getPlayer().sendMessage(
								ChatColor.BLUE + "[PlotMe] " + ChatColor.WHITE
										+ "Plot resetting...");
						Bukkit.getServer().dispatchCommand(e.getPlayer(), "plotme claim");
						Bukkit.getServer().dispatchCommand(e.getPlayer(), "plotme clear");
						Bukkit.getServer().dispatchCommand(e.getPlayer(), "plotme dispose");
						e.setCancelled(true);
					}
				}
				if (e.getMessage().toLowerCase().startsWith("/plotme dispose")) {
					Bukkit.getServer().dispatchCommand(e.getPlayer(), "plotme clear");
				}
			}
		}
	}
	
	@EventHandler (priority=EventPriority.HIGHEST)
	public void BlockFromTo(BlockFromToEvent e) {
		if (e.isCancelled()) {
			Location loc = e.getToBlock().getLocation();
			if (loc.getWorld().getName().equals("Build")) {
//				String id = PlotManager.getPlotId(loc);
//				if (getPlot(id) != null)
//					return;
				String x1 = PlotManager.getPlotId(loc.clone().add(5, 0, 0));
				String x2 = PlotManager.getPlotId(loc.clone().add(-5, 0, 0));
				String y1 = PlotManager.getPlotId(loc.clone().add(0, 0, 5));
				String y2 = PlotManager.getPlotId(loc.clone().add(0, 0, -5));
				boolean allowed = false;
				if (getPlot(x1) != null && getPlot(x2) != null)
					allowed = getPlot(x1).getOwner().equals(getPlot(x2).getOwner());
				if (!allowed && getPlot(y1) != null && getPlot(y2) != null)
					allowed = getPlot(y1).getOwner().equals(getPlot(y2).getOwner());
				if (allowed) {
					e.setCancelled(false);
					return;
				}
				String cor1 = PlotManager.getPlotId(loc.clone().add(5, 0, 5));
				String cor2 = PlotManager.getPlotId(loc.clone().add(-5, 0, 5));
				String cor3 = PlotManager.getPlotId(loc.clone().add(5, 0, 5));
				String cor4 = PlotManager.getPlotId(loc.clone().add(-5, 0, -5));
				if (getPlot(cor1) != null && getPlot(cor2) != null && getPlot(cor3) != null && getPlot(cor4) != null)
					if (getPlot(cor1).getOwner().equals(getPlot(cor2).getOwner()) && getPlot(cor1).getOwner().equals(getPlot(cor3).getOwner()) && getPlot(cor1).getOwner().equals(getPlot(cor4).getOwner())) {
						e.setCancelled(false);
					}
			}
		}
	}
	
	@EventHandler (priority=EventPriority.HIGHEST)
	public void onPlayerBucketEmpty(PlayerBucketEmptyEvent e) {
		if (e.isCancelled()) {
			Location loc = e.getBlockClicked().getLocation();
			if (loc.getWorld().getName().equals("Build")) {
//				String id = PlotManager.getPlotId(loc);
//				if (getPlot(id) != null)
//					return;
				String x1 = PlotManager.getPlotId(loc.clone().add(5, 0, 0));
				String x2 = PlotManager.getPlotId(loc.clone().add(-5, 0, 0));
				String y1 = PlotManager.getPlotId(loc.clone().add(0, 0, 5));
				String y2 = PlotManager.getPlotId(loc.clone().add(0, 0, -5));
				boolean allowed = false;
				if (getPlot(x1) != null && getPlot(x2) != null)
					allowed = getPlot(x1).getOwner().equals(getPlot(x2).getOwner()) && getPlot(x1).isAllowed(e.getPlayer().getName());
				if (!allowed && getPlot(y1) != null && getPlot(y2) != null)
					allowed = getPlot(y1).getOwner().equals(getPlot(y2).getOwner()) && getPlot(y1).isAllowed(e.getPlayer().getName());
				if (allowed) {
					e.setCancelled(false);
					return;
				}
				String cor1 = PlotManager.getPlotId(loc.clone().add(5, 0, 5));
				String cor2 = PlotManager.getPlotId(loc.clone().add(-5, 0, 5));
				String cor3 = PlotManager.getPlotId(loc.clone().add(5, 0, 5));
				String cor4 = PlotManager.getPlotId(loc.clone().add(-5, 0, -5));
				if (getPlot(cor1) != null && getPlot(cor2) != null && getPlot(cor3) != null && getPlot(cor4) != null)
					if (getPlot(cor1).getOwner().equals(getPlot(cor2).getOwner()) && getPlot(cor1).getOwner().equals(getPlot(cor3).getOwner()) && getPlot(cor1).getOwner().equals(getPlot(cor4).getOwner())) {
						e.setCancelled(false);
					}
			}
		}
	}
	
	@EventHandler (priority=EventPriority.HIGHEST)
	public void onPistonExtendEvent(BlockPistonExtendEvent e) {
		if (e.isCancelled()) {
			List<Block> blocks = e.getBlocks();
			if (blocks.size() > 0 && blocks.get(0).getLocation().getWorld().getName().equals("Build"))
				for (int blocknum = 0; blocknum < blocks.size(); blocknum++) {
					Location loc = blocks.get(blocknum).getLocation();
					if (loc.getWorld().getName().equals("Build")) {
						String x1 = PlotManager.getPlotId(loc.clone().add(5, 0, 0));
						String x2 = PlotManager.getPlotId(loc.clone().add(-5, 0, 0));
						String y1 = PlotManager.getPlotId(loc.clone().add(0, 0, 5));
						String y2 = PlotManager.getPlotId(loc.clone().add(0, 0, -5));
						boolean allowed = false;
						if (getPlot(x1) != null && getPlot(x2) != null)
							allowed = getPlot(x1).getOwner().equals(getPlot(x2).getOwner());
						if (!allowed && getPlot(y1) != null && getPlot(y2) != null)
							allowed = getPlot(y1).getOwner().equals(getPlot(y2).getOwner());
						if (allowed) {
							if (blocknum+1 != blocks.size()) {
								continue;
							} else {
								e.setCancelled(false);
								return;
							}
						} else {
							String cor1 = PlotManager.getPlotId(loc.clone().add(5, 0, 5));
							String cor2 = PlotManager.getPlotId(loc.clone().add(-5, 0, 5));
							String cor3 = PlotManager.getPlotId(loc.clone().add(5, 0, 5));
							String cor4 = PlotManager.getPlotId(loc.clone().add(-5, 0, -5));
							if (getPlot(cor1) != null && getPlot(cor2) != null && getPlot(cor3) != null && getPlot(cor4) != null)
								if (getPlot(cor1).getOwner().equals(getPlot(cor2).getOwner()) && getPlot(cor1).getOwner().equals(getPlot(cor3).getOwner()) && getPlot(cor1).getOwner().equals(getPlot(cor4).getOwner())) {
									if (blocknum != blocks.size()) {
										continue;
									} else {
										e.setCancelled(false);
										return;
									}
								}
						}
					}
				}
		}
	}
	
	@EventHandler (priority=EventPriority.HIGHEST)
	public void onPistonRetractEvent(BlockPistonRetractEvent e) {
		if (e.isCancelled()) {
			Location loc = e.getBlock().getLocation();
			if (loc.getWorld().getName().equals("Build")) {
				String x1 = PlotManager.getPlotId(loc.clone().add(5, 0, 0));
				String x2 = PlotManager.getPlotId(loc.clone().add(-5, 0, 0));
				String y1 = PlotManager.getPlotId(loc.clone().add(0, 0, 5));
				String y2 = PlotManager.getPlotId(loc.clone().add(0, 0, -5));
				boolean allowed = false;
				if (getPlot(x1) != null && getPlot(x2) != null)
					allowed = getPlot(x1).getOwner().equals(getPlot(x2).getOwner());
				if (!allowed && getPlot(y1) != null && getPlot(y2) != null)
					allowed = getPlot(y1).getOwner().equals(getPlot(y2).getOwner());
				if (allowed) {
					e.setCancelled(false);
					return;
				}
				String cor1 = PlotManager.getPlotId(loc.clone().add(5, 0, 5));
				String cor2 = PlotManager.getPlotId(loc.clone().add(-5, 0, 5));
				String cor3 = PlotManager.getPlotId(loc.clone().add(5, 0, 5));
				String cor4 = PlotManager.getPlotId(loc.clone().add(-5, 0, -5));
				if (getPlot(cor1) != null && getPlot(cor2) != null && getPlot(cor3) != null && getPlot(cor4) != null)
					if (getPlot(cor1).getOwner().equals(getPlot(cor2).getOwner()) && getPlot(cor1).getOwner().equals(getPlot(cor3).getOwner()) && getPlot(cor1).getOwner().equals(getPlot(cor4).getOwner())) {
						e.setCancelled(false);
					}
			}
		}
	}


	private void log(String info) {
		plugin.getLogger().info("<PlotMeOverride> " + info);
	}
} public class TnTPunch {
	private CustomPlugin plugin;

	public TnTPunch(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}

	private ArrayList<Player> disabledTnTPunch = new ArrayList<Player>();
	
	public boolean onCommand(CommandSender sender) {
		if (sender instanceof Player) {
			Player player = (Player) sender;
			if (!player.getWorld().getName().equals("Destruction")) {
				player.sendMessage(ChatColor.RED + "You can only toggle the tnt punch in the Destruction World.");
			} else {
				if (disabledTnTPunch.contains(player)) {
					disabledTnTPunch.remove(player);
					player.sendMessage(ChatColor.GREEN + "TNT punch has been reenabled for you.");
				} else {
					disabledTnTPunch.add(player);
					player.sendMessage(ChatColor.GREEN + "TNT punch has been removed for you.");
				}
			}
			return true;
		} else {
			return false;
		}
	}
	
	public void onPlayerInteract(final PlayerInteractEvent event) { 
		Player player = event.getPlayer();
		if (player.getWorld().getName().equals("Destruction")) {
			if (!disabledTnTPunch.contains(player))
				Bukkit.dispatchCommand(player, "tnt");
		}
	}
	
	public void log(String info) {
		plugin.getLogger().info("<TnTPunch> " + info);
	}
} public class EWBlockFenceWalk {
	private CustomPlugin plugin;

	public EWBlockFenceWalk(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	public void onPlayerMove(PlayerMoveEvent event)
	{
		Player player = event.getPlayer();
		if (player.getWorld().getName().equals("EventWorld") && player.getLocation().add(0,-1,0).getBlock().getType().equals(Material.FENCE)) {
			Location l = player.getLocation();
			if (l.getY()-l.getBlockY() >= .5) {
				Block b = search(l);
				if (b != null) {
					player.teleport(new Location(b.getWorld(), b.getX() + .5, b.getY() + 1.5, b.getZ() + .5, l.getYaw(), l.getPitch()));
				}
			}
		}
	}
	
	public Block search(Location l) {
		for (int y = -3; y <= 0; y++) {
			Block b = l.getWorld().getBlockAt(l.getBlockX()-1, l.getBlockY()+y, l.getBlockZ());
			if (b.getType().equals(Material.BEDROCK))
				return b;
		}
		for (int y = -3; y <= 0; y++) {
			Block b = l.getWorld().getBlockAt(l.getBlockX()+1, l.getBlockY()+y, l.getBlockZ());
			if (b.getType().equals(Material.BEDROCK))
				return b;
		}
		
		for (int y = -3; y <= 0; y++) {
			Block b = l.getWorld().getBlockAt(l.getBlockX(), l.getBlockY()+y, l.getBlockZ()-1);
			if (b.getType().equals(Material.BEDROCK))
				return b;
		}
		for (int y = -3; y <= 0; y++) {
			Block b = l.getWorld().getBlockAt(l.getBlockX(), l.getBlockY()+y, l.getBlockZ()+1);
			if (b.getType().equals(Material.BEDROCK))
				return b;
		}

		for (int y = -3; y <= 0; y++) {
			Block b = l.getWorld().getBlockAt(l.getBlockX()-1, l.getBlockY()+y, l.getBlockZ()-1);
			if (b.getType().equals(Material.BEDROCK))
				return b;
		}
		for (int y = -3; y <= 0; y++) {
			Block b = l.getWorld().getBlockAt(l.getBlockX()+1, l.getBlockY()+y, l.getBlockZ()-1);
			if (b.getType().equals(Material.BEDROCK))
				return b;
		}
		
		for (int y = -3; y <= 0; y++) {
			Block b = l.getWorld().getBlockAt(l.getBlockX()-1, l.getBlockY()+y, l.getBlockZ()+1);
			if (b.getType().equals(Material.BEDROCK))
				return b;
		}
		for (int y = -3; y <= 0; y++) {
			Block b = l.getWorld().getBlockAt(l.getBlockX()+1, l.getBlockY()+y, l.getBlockZ()+1);
			if (b.getType().equals(Material.BEDROCK))
				return b;
		}
		
		return null;
	}

	public void log(String info) {
		plugin.getLogger().info("<EWBlockFenceWalk> " + info);
	}
} public class EWButtons {
	private CustomPlugin plugin;

	public EWButtons(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}

	public void onPlayerInteract(PlayerInteractEvent event) { 
		Player player = event.getPlayer();
		if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
			Location loc = event.getClickedBlock().getLocation();
			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), -458, 64, -504))) {
				Bukkit.dispatchCommand(player, "warp sg");
			}

			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), 10004, 65, 10000))) {
				Bukkit.dispatchCommand(player, "sg join 1");
			}
			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), 10004, 65, 10001))) {
				Bukkit.dispatchCommand(player, "sg join 2");
			}
			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), 10004, 65, 10002))) {
				Bukkit.dispatchCommand(player, "sg join 3");
			}
			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), 10004, 65, 10003))) {
				Bukkit.dispatchCommand(player, "sg join 4");
			}
			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), 10004, 65, 10004))) {
				Bukkit.dispatchCommand(player, "sg join 5");
			}

			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), 9995, 65, 10004))) {
				Bukkit.dispatchCommand(player, "sg join 1");
			}
			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), 9995, 65, 10003))) {
				Bukkit.dispatchCommand(player, "sg join 2");
			}
			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), 9995, 65, 10002))) {
				Bukkit.dispatchCommand(player, "sg join 3");
			}
			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), 9995, 65, 10001))) {
				Bukkit.dispatchCommand(player, "sg join 4");
			}
			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), 9995, 65, 10000))) {
				Bukkit.dispatchCommand(player, "sg join 5");
			}

			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), -453, 64, -504))) {
				Bukkit.dispatchCommand(player, "ma join");
			}
			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), -460, 64, -506))) {
				Bukkit.dispatchCommand(player, "spleef join");
			}
			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), -460, 64, -511))) {
				Bukkit.dispatchCommand(player, "pb join");
			}
			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), -451, 64, -511))) {
				Bukkit.dispatchCommand(player, "hns join");
			}
			if (loc.equals(new Location(Bukkit.getWorld("EventWorld"), -451, 64, -506))) {
				Bukkit.dispatchCommand(player, "ctf join");
			}
		}
	}
	
	public void log(String info) {
		plugin.getLogger().info("<EWButtons> " + info);
	}
} public class BeastSprint {
	private CustomPlugin plugin;

	public BeastSprint(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		if (plugin.getServer().getPluginManager().getPlugin("Factions") != null) {
			factionsEnabled = true;
			Faction faction = FactionColls.get().getForWorld("Survival").getByName("SafeZone");
			Set<PS> chunks_ps = BoardColls.get().getChunks(faction);
			for (PS ps : chunks_ps) {
				safezone.add(ps.asBukkitChunk());
			}
		}
		Player insanity = Bukkit.getPlayer("InsanityGaz");
		if (insanity != null)
			disabledSprint.add(insanity);
		log("Enabled");
	}
	private ArrayList<Player> disabledSprint = new ArrayList<Player>();
	boolean factionsEnabled = false;
	private ArrayList<Chunk> safezone = new ArrayList<Chunk>();

	public boolean onCommand(CommandSender sender) {
		if (sender instanceof Player) {
			Player player = (Player) sender;
//			if (!player.hasPermission("beastsprint.can")) {
//				player.sendMessage(ChatColor.GREEN + "You can't use beast sprint");
//				return true;
//			}
			if (disabledSprint.contains(player)) {
				player.sendMessage(ChatColor.GREEN + "Beast Sprint enabled.");
				disabledSprint.remove(player);
			} else {
				player.sendMessage(ChatColor.GREEN + "Beast Sprint disabled.");
				disabledSprint.add(player);
			}
		}
		return true;
	}
	
	@SuppressWarnings("deprecation")
	public void onPlayerMoveEvent(PlayerMoveEvent event) {
		final Player player = event.getPlayer();
		Location loc = player.getLocation();
		Block glass = player.getLocation().add(0,-2,0).getBlock();
		//(factionsEnabled && safezone.contains(loc.getChunk()))
		if ((player.hasPermission("beastsprint.can") || (glass.getType().equals(Material.GLASS) && glass.getData() == (byte)2) || loc.getWorld().getName().equals("Build")) && !disabledSprint.contains(player)) {
			if (player.isSprinting()) {
				if ((player.hasPermission("beastsprint.can")))
					player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 200, 10));
				else
					player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 200, 5));
				player.getWorld().playEffect(loc, Effect.MOBSPAWNER_FLAMES, 1, 50);
			} else {
				player.removePotionEffect(PotionEffectType.SPEED);
			}
		}
	}
	
	public void log(String info) {
		plugin.getLogger().info("<BeastSprint> " + info);
	}
} public class BungeeGlobalCommand {
	private static CustomPlugin plugin;

	public BungeeGlobalCommand(CustomPlugin plugin) {
		BungeeGlobalCommand.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	//2.55
	public void onBungeeMessageReceived(String channel, Player player, byte[] message) {
		DataInputStream in = new DataInputStream(new ByteArrayInputStream(message));
		try {
			String subChannel = in.readUTF();
			if (subChannel.equals("DDCustomPlugin_GBCommand")) {
				short len = in.readShort();
				byte[] msgbytes = new byte[len];
				in.readFully(msgbytes);

				DataInputStream msgin = new DataInputStream(new ByteArrayInputStream(msgbytes));
				String command = msgin.readUTF();
				log(command);
				plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), command);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void sendCommand(String cmd) {
		ByteArrayOutputStream b = new ByteArrayOutputStream();
		DataOutputStream out = new DataOutputStream(b);
		
		try {
			out.writeUTF("Forward");
			out.writeUTF("ALL");
			out.writeUTF("DDCustomPlugin_GBCommand");

			ByteArrayOutputStream msgbytes = new ByteArrayOutputStream();
			DataOutputStream msgout = new DataOutputStream(msgbytes);
			msgout.writeUTF(cmd);

			out.writeShort(msgbytes.toByteArray().length);
			out.write(msgbytes.toByteArray());
		} catch (IOException e) {
			e.printStackTrace();
		}

		// OR, if you don't need to send it to a specific player
		Player p = Bukkit.getOnlinePlayers()[0];
		 
		p.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
	}
	
	public boolean onCommand(CommandSender sender, String[] args) {
		if (!sender.hasPermission("customplugin.globalcommand"))
			return true;
		String cmd = "";
		for (int i = 0; i < args.length; i++) {
			cmd += args[i] + " ";
		}
		cmd = cmd.substring(0, cmd.length()-1);
		sendCommand(cmd);
		plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), cmd);
		sender.sendMessage(ChatColor.BLUE + "Complete: " + ChatColor.DARK_GRAY + "/" + cmd);
		return true;
	}

	public void log(String info) {
		plugin.getLogger().info("<BungeeGlobalCommand> " + info);
	}
} public class Chat implements Listener {
	public static CustomPlugin plugin;
	public static ChatSQL sql;
	public static ChatUtils utils;
	public static ChatFacsTowns f_t;
	public static Permission perms = null;

	public Map<String, String> cusses = new HashMap<String, String>();
	public Map<Player, Integer> cussesNum = new HashMap<Player, Integer>();
	public ArrayList<String> cussMax = new ArrayList<String>();
	public ArrayList<CommandSender> disabledSpys = new ArrayList<CommandSender>();
	public Map<Player, String> spamData = new HashMap<Player, String>(); //timestamp;total;lastphrase
	public Map<String, String> lastMsg = new HashMap<String, String>();
	
	private ArrayList<String> globalPlayerList = new ArrayList<String>();
	
	public boolean marriageEnabled = true;

	public Chat(CustomPlugin plugin) {
		Chat.plugin = plugin;
	}
	@SuppressWarnings("deprecation")
	public void enable() {
		plugin.getServer().getPluginManager().registerEvents(this, plugin);
		setupPermissions();
		addCusses();
		createCussLoop();
		sql = new ChatSQL(this);
		utils = new ChatUtils(this);
		for (Plugin pl : Bukkit.getServer().getPluginManager().getPlugins()) {
			if (pl.getName().contains("Faction")) {
				f_t = new ChatFacsTowns(this);
				log("Factions/Towny Server Detected");
			}
		}
		Bukkit.getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
			@Override
			public void run() {
				ByteArrayOutputStream b = new ByteArrayOutputStream();
				DataOutputStream out = new DataOutputStream(b);
				try {
					out.writeUTF("PlayerList");
					out.writeUTF("ALL");
				} catch (Exception e2) {}
				if (Bukkit.getOnlinePlayers().length > 0) {
					Bukkit.getOnlinePlayers()[0].sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
				}
			}
		}, 5, 20*15);
		log("Enabled");
	}
	
	private String convertMsg(Player player, String msg) {
		msg = utils.removeCussWords(msg, true, player, !player.hasPermission("ddchat.censorbypass"), utils.getChannelPrefix(player));
		if (player.hasPermission("ddchat.color")) {
			msg = ChatColor.translateAlternateColorCodes('&', msg); 
		} else {
			msg = utils.changeCussColors(msg);
		}
		if (!player.hasPermission("ddchat.caps"))
			msg = utils.removeCAPS(msg);
		msg = utils.getDate(player) + utils.getWorld(player) + " " + utils.getDonorPrefix(player) + utils.getNamePrefix(player)
				+ utils.getName(player) + ChatColor.GRAY + ": " + utils.getChannelPrefix(player)
				+ msg;
		return msg;
	}

	private void addCusses() {
		cusses.put("fuck", "f<uc>k");
		cusses.put("cunt", "c<u>nt");
		cusses.put("sex", "s<e>x");
		cusses.put("shit", "sh<i>t");
		cusses.put("cock", "c<o>ck");
		cusses.put("dick", "d<i>ck");
//		cusses.put("gay", "g<a>y");
		cusses.put("penis", "p<eni>s");
		cusses.put("bitch", "b<i>tch");
		cusses.put("nigger", "n<igg>er");
		cusses.put("nigga", "n<igg>er");
		cusses.put("slut", "sl<u>t");
		cusses.put("lesbian", "l<e>sbian");
		cusses.put("vagina", "vag<i>na");
		cusses.put("tits", "t<i>ts");
		cusses.put("tittie", "t<i>ttie");
		cusses.put("boob", "b<oo>b");
		cusses.put("fag", "f<a>g");
		cusses.put("cripple", "cr<i>pple");
		cusses.put("pussy", "p<u>ssy");
		cusses.put("whore", "wh<o>re");
		cusses.put("bastard", "b<a>stard");
		cusses.put("boner", "b<o>ner");
		cusses.put("dilldo", "d<i>lldo");
		cusses.put("asshole", "a<ss>hole");
		cusses.put(" ass ", " a<ss> ");
//		cusses.put("asses", "a<ss>es");
		cusses.put("queef", "qu<e>ef");
		cusses.put("valde", "välde");
	}
	
	public void addToCussNum(final Player player) {
		plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
			@Override
			public void run() {
				if (cussesNum.containsKey(player)) {
					cussesNum.put(player, cussesNum.get(player) + 1);
				} else {
					cussesNum.put(player, 1);
				}
				if (cussesNum.get(player) > 5) {
					String group = perms.getPlayerGroups(player)[0];
					String msg = "You may not curse more than 5 times a minute!";
					if (!(group.contains("Player")
							|| group.contains("Respected") || group
							.contains("Owner"))) {
						if (cussMax.contains(player.getName())) {
							Bukkit.getServer().dispatchCommand(
									Bukkit.getConsoleSender(),
									"manuaddp " + player.getName()
									+ " -ddchat.censorbypass");
							msg = "You have lost your donor permissions for cursing freely. No refunds.";
						} else {
							msg += "\n\nYou will lose your cursing permissions next time you do that.";
							cussMax.add(player.getName());
						}
					}
					Bukkit.getServer().dispatchCommand(
							Bukkit.getConsoleSender(),
							"kick " + player.getName() + " " + msg);
					cussesNum.put(player, 0);
				}
			}
		}, 1);
	}
	
	
	private Player lastSpammer = null;
	
	public void checkSpam(Player player, String msg) {
		double currTimestamp = System.currentTimeMillis()/1000;
		String[] data;
		if (spamData.containsKey(player)) {
			data = spamData.get(player).split(";");
		} else {
			spamData.put(player, currTimestamp + ";1;" + msg);
			return;
		}
		double timestamp = Double.valueOf(data[0]);
		int total = Integer.parseInt(data[1]);
		String lastMessage = data[2];
//		System.out.println(timestamp + ";" + total + ";" + lastMessage);
//		System.out.println(spamData.toString());
		if (lastMessage.equals(msg) && currTimestamp-timestamp < 5) {
			if (currTimestamp-timestamp < .25) {
				final String name = player.getName();
				plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
					@Override 
					public void run() {
						Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "mute " + name + " 30s");
						Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "kick " + name + " SPAM! 1 time only plz");
					}
				}, 1);
			}
			total++;
		} else if (lastSpammer != null && player == lastSpammer && currTimestamp-timestamp < 2) {
			total++;
		} else if (player == lastSpammer && currTimestamp-timestamp < .25) {
			total++;
		} else {
			total = 1;
		}
		if (total >= 3) {
			final String name = player.getName();
			plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
				@Override 
				public void run() {
					Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "mute " + name);
					Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "kick " + name + " SPAM! Talk less plz");
				}
			}, 1);
		}
		String newData = currTimestamp + ";" + total + ";" + msg;
//		System.out.println(newData);
//		System.out.println("msg="+msg+";lastMessage="+lastMessage);
		lastSpammer = player;
		spamData.put(player, newData);
	}	

	@SuppressWarnings("deprecation")
	private void createCussLoop() {
		plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
			@Override
			public void run() {
				for (Player p : cussesNum.keySet()) {
					cussesNum.put(p, 0);
				}
			}
		}, 100L, 20 * 60);
	}
	
	public boolean msgCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
		if (args.length < 2) {
			msg(sender, "/msg [Player] [Message]");
			return true;
		}
		String msg = "";
		for (int i = 1; i < args.length; i++)
			msg += args[i] + " ";
		
		if (!(sender instanceof Player)) {
			Player consoleReciever = Bukkit.getPlayer(args[0]);
			if (consoleReciever == null) {
				log("Player not found :(");
				return true;
			}
			msg = "Offline " + ChatColor.DARK_PURPLE + "Esaych" + ChatColor.AQUA + " --" + ChatColor.BLUE + "> " + utils.getNamePrefix(consoleReciever) + "You" + ChatColor.WHITE + ": " + msg;
			consoleReciever.sendMessage(msg);
			log(msg);
			return true;
		}
		Player player = (Player) sender;
		
		sql.logChat(player, msg, args[0]);
		
		Player reciever = Bukkit.getPlayer(args[0]);
		if (reciever == null) {
			boolean playerFound = false;
			for (String playerName : globalPlayerList) {
				if (playerName.toLowerCase().contains(args[0].toLowerCase())) {
					if (sql.getIgnoredPlayers(playerName).contains(player.getName())) {
						msg(player, playerName + " is ignoring you");
						return true;
					}
					msg = utils.removeCussWords(msg, true, player, !player.hasPermission("ddchat.censorbypass"), utils.getChannelPrefix(player));
					if (player.hasPermission("ddchat.color"))
						msg = ChatColor.translateAlternateColorCodes('&', msg);

					ByteArrayOutputStream b = new ByteArrayOutputStream();
					DataOutputStream out = new DataOutputStream(b);

					try {
						out.writeUTF("Forward");
						out.writeUTF("ALL");
						out.writeUTF("DDCustomPlugin_Chat");

						ByteArrayOutputStream msgbytes = new ByteArrayOutputStream();
						DataOutputStream msgout = new DataOutputStream(msgbytes);
						msgout.writeUTF("playermsg");
						msgout.writeUTF(utils.getDName(player));
						msgout.writeUTF(playerName);
						msgout.writeUTF(msg);

						out.writeShort(msgbytes.toByteArray().length);
						out.write(msgbytes.toByteArray());
					} catch (Exception e2) {}
					player.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
					player.sendMessage(utils.getNamePrefix(player) + "You" + ChatColor.AQUA + " --" + ChatColor.BLUE + "> " + ChatColor.WHITE + playerName + ChatColor.WHITE + ": " + msg);
					lastMsg.put(playerName, player.getName());
					playerFound = true;
					break;
				}
			}
			if (!playerFound) {
				msg(sender, "The player " + args[0] + " does not seem to exist.");
			}
			return true;
		}
		
		
		if (sql.getIgnoredPlayers(player.getName()).contains(reciever.getName())) {
			msg(player, "You can't message people you are ignoring");
			return true;
		}

		if (sql.getIgnoredPlayers(reciever.getName()).contains(player.getName())) {
			msg(player, reciever.getName() + " is ignoring you.");
			return true;
		}
		
		
		msg = utils.removeCussWords(msg, true, player, !player.hasPermission("ddchat.censorbypass"), utils.getChannelPrefix(player));
		if (player.hasPermission("ddchat.color"))
			msg = ChatColor.translateAlternateColorCodes('&', msg);
		reciever.sendMessage(utils.getDName(player) + ChatColor.AQUA + " --" + ChatColor.BLUE + "> " + utils.getNamePrefix(reciever) + "You" + ChatColor.WHITE + ": " + msg);
		player.sendMessage(utils.getNamePrefix(player) + "You" + ChatColor.AQUA + " --" + ChatColor.BLUE + "> " + utils.getDName(reciever) + ChatColor.WHITE + ": " + msg);
//		lastMsg.put(player, reciever);
		lastMsg.put(reciever.getName(), player.getName());
		return true;
	}
	
	public boolean rCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
		if (!(sender instanceof Player)) {
			msg(sender, "You realize console's dont have any msg history...");
			return true;
		}
		if (!lastMsg.containsKey(sender.getName())) {
			msg(sender, "Nobody has messaged you!");
			return true;
		}
//		if (Bukkit.getPlayer(lastMsg.get(sender.getName())) == null) {
//			msg(sender, "They are not online!");
//			return true;
//		}
		String msg = "";
		for (int i = 0; i < args.length; i++)
			msg += args[i] + " ";
		return msgCommand(sender, cmd, commandLabel,
				new String[] { lastMsg.get(sender.getName()), msg });
	}

	public boolean chCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
		/*
		 * l = local, 100 blocks
		 * w = world
		 * g = global
		 * f = faction chat
		 * s = staff chat
		 * n = towny nation
		 * t = towns
		 */
		if (!(sender instanceof Player)) {
			msg(sender, "NO CHAT FOR YOU");
			return true;
		}
		if (args.length == 0 && !(commandLabel.equalsIgnoreCase("sc"))) {
			msg(sender, "Try /ch <channel>");
			if (f_t != null) {
				msg(sender, "&aFaction: &bSends to faction members");
				msg(sender, "&6Town: &bSend to only town members");
				msg(sender, "&6&oNation: &bSend to all in your nation");
			}
			msg(sender, "&eLocal: &bOnly receive chat from players within 100 blocks");
			msg(sender, "World: Only receive chat from players in your world");
			msg(sender, "&fGlobal: &bGet all chat messages from everyone");
			msg(sender, "&cBecause you are in a smaller channel doesn't mean others don't get your messages when they are in global");
			return true;
		} 
		if (!(commandLabel.equalsIgnoreCase("sc"))) {
			char channel = args[0].toLowerCase().charAt(0);
			if (channel == 'l') {
				sql.setChannel(sender.getName(), "l");
				msg(sender, "Channel set to " + utils.getChannelPrefix((Player) sender) + "&oLocal");
				return true;
			}
			if (channel == 'w') {
				sql.setChannel(sender.getName(), "w");
				msg(sender, "Channel set to " + utils.getChannelPrefix((Player) sender) + "&oWorld");
				return true;
			}
			if (channel == 'g') {
				sql.setChannel(sender.getName(), "g");
				msg(sender, "Channel set to " + utils.getChannelPrefix((Player) sender) + "&oGlobal");
				return true;
			}
			if (channel == 'f') {
				if (f_t != null) {
					if (f_t.getFacName((Player)sender).equals("")) {
						msg(sender, "You are not in a faction");
						return true;
					}
					sql.setChannel(sender.getName(), "f");
					msg(sender, "Channel set to " + utils.getChannelPrefix((Player) sender) + "&oFaction");
					return true;
				}
			}
			if (channel == 't') {
				if (f_t != null) {
					if (f_t.testTown((Player)sender)) {
						sql.setChannel(sender.getName(), "t");
						msg(sender, "Channel set to " + utils.getChannelPrefix((Player) sender) + "&oTown");
						return true;
					} else {
						msg(sender, "You are not in a town");
						return true;
					}
				}
			}
			if (channel == 'n') {
				if (f_t != null) {
					if (f_t.testNation((Player)sender)) {
						sql.setChannel(sender.getName(), "n");
						msg(sender, "Channel set to " + utils.getChannelPrefix((Player) sender) + "&oNation");
						return true;
					} else {
						msg(sender, "You are not in a nation");
						return true;
					}
				}
			}
			if (channel == 's') {
				if (!sender.hasPermission("ddchat.staffchat")) {
					msg(sender, "You don't have permission for staff chat.");
					return true;
				}
				sql.setChannel(sender.getName(), "s");
				msg(sender, "Channel set to " + utils.getChannelPrefix((Player) sender) + "&oStaff Chat");
				return true;
			}
		} else {
			if (!sender.hasPermission("ddchat.staffchat")) {
				msg(sender, "You don't have permission for staff chat.");
				return true;
			}
			String c = sql.getChannel(sender.getName());
			if (c != null && c.equals("s")) {
				sql.setChannel(sender.getName(), "g");
				msg(sender, "Channel set to &f&oGlobal Chat");
			} else {
				sql.setChannel(sender.getName(), "s");
				msg(sender, "Channel set to &c&oStaff Chat");
			}
			return true;
		}
		msg(sender, "Thats not a channel! Try:");
		msg(sender, "&aFaction: &bSends to faction members");
		msg(sender, "&6Town: &bSend to only town members");
		msg(sender, "&6&oNation: &bSend to all in your nation");
		msg(sender, "&eLocal: &bOnly receive chat from players within 100 blocks");
		msg(sender, "World: Only receive chat from players in your world");
		msg(sender, "&fGlobal: &bGet all chat messages from everyone");
		msg(sender, "&cBecause you are in a smaller channel doesn't mean others don't get your messages when they are in global");
		return true;
	}
	
	public boolean badProfileCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
		if (sender.hasPermission("ddchat.givesbadprofiles")) {
			if (args.length == 0) {
				msg(sender, "You must specify a player");
				return true;
			}
			Player player = Bukkit.getPlayer(args[0]);
			if (player == null) {
				msg(sender, "Player not found");
				return true;
			}
			if (sql.getBadProfile(player.getName())) {
				sql.setBadProfile(player.getName(), false);
				msg(sender, player.getName() + " has been removed their badprofile");
			} else {
				sql.setBadProfile(player.getName(), true);
				msg(sender, player.getName() + " has been given a badprofile");
			}
			return true;
		} else {
			msg(sender, "You don't have permission for this command");
			return true;
		}
	}
	
	public boolean spyCommand(CommandSender sender) {
		if (!sender.hasPermission("ddchat.commandsnoop")) {
			return true;
		}
		if (disabledSpys.contains(sender)) {
			disabledSpys.remove(sender);
			sender.sendMessage(ChatColor.GREEN + "Command Spy has been enabled");
		} else {
			disabledSpys.add(sender);
			sender.sendMessage(ChatColor.GREEN + "Command Spy has been disabled");
		}
		return true;
	}
	
	private Map<Player, String> marriageQueue = new HashMap<Player, String>(); //Proposed To, Proposer:ScheduleID
	
	public boolean dateCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
		if (marriageEnabled) {
			if (args.length == 0) {
				mmsg(sender, ChatColor.GREEN + "-------  Dating Help  -------");
				mmsg(sender, "Type /date 'player' to ask someone out");
				mmsg(sender, "Type /dump to dump your current date");
				mmsg(sender, "Right click next to your date to kiss them");
				mmsg(sender, ChatColor.GREEN + "--------------------------");
				return true;
			}
			final Player player = Bukkit.getPlayer(args[0]);
			if (sql.getDatingPartner(sender.getName()) != null) {
				if (sql.getDatingPartner(sender.getName()).equals(player.getName())) {
					mmsg(sender, "You must dump " + sql.getDatingPartner(sender.getName()) + " before you date another person!");
				} else {
					mmsg(sender, "You are already dating someone.");
				}
				return true;
			}
			if (sender instanceof Player) {
				if (sender.isOp()) {
					if (args[0].equalsIgnoreCase("disable")) {
						marriageEnabled = false;
						mmsg(sender, "Dating Disabled");
						return true;
					}
					if (args[0].equalsIgnoreCase("enable")) {
						marriageEnabled = false;
						mmsg(sender, "Dating Enabled");
						return true;
					}
				}
				if (marriageQueue.containsKey(sender) && args[0].equalsIgnoreCase("reject")) {
					Bukkit.broadcastMessage(ChatColor.AQUA + "[" + ChatColor.RED + "Dating" + ChatColor.AQUA + "] " + ChatColor.RED +   
							sender.getName() + " rejected " + marriageQueue.get(sender) + ChatColor.WHITE + "!");
					marriageQueue.remove(sender);
					return true;
				}
				//check if actually online
				if (player == null) {
					mmsg(sender, "You must specify an online player.");
					return true;
				}
				if (player == sender) {
					mmsg(sender, "You can't date yourself :/");
					return true;
				}
				//check if they have a request
				if (marriageQueue.containsKey(sender)) {
					if (marriageQueue.get(sender).equalsIgnoreCase(player.getName())) {
						marry(Bukkit.getPlayer(args[0]), (Player) sender);
					} else {
						mmsg(sender, "You have a pending request from " + marriageQueue.get(sender) + "!");
						mmsg(sender, "You must '/date reject' them first.");
					}
					return true;
				}
				//check if they're a dirty cheater
				for (Player p : marriageQueue.keySet()) {
					String old = p.getName();
					if (sender.getName().equals(marriageQueue.get(p))) {
						if (!player.getName().equals(old)) {
							mmsg(sender, "What about " + old + "?");
							mmsg(sender, "You dirty cheater!");
							marriageQueue.remove(sender);
							marriageQueue.remove(p);
							marriageQueue.remove(player);
							Player dumped = Bukkit.getPlayer(old);
							if (dumped != null) {
								mmsg(dumped, sender.getName() + " ditched you for " + utils.getPlayerListName(player));
							}
						} else {
							mmsg(sender, "You are already requesting them!");
							return true;
						}
					}
				}
				
				if (!utils.getDate(player).equals("")) {
					mmsg(sender, player.getName() + " is already dating!");
					return true;
				}
				
				marriageQueue.put(player, sender.getName());

				mmsg(player, ChatColor.AQUA + "----------------------------------------");
				mmsg(player, utils.getPlayerListName((Player) sender)+ ChatColor.AQUA + " wants to date you!");
				mmsg(player, "Type '/date " + utils.getPlayerListName((Player) sender) + ChatColor.AQUA + "' to accept!");
				mmsg(player, "Or '/date reject' if you want to break their heart.");
				mmsg(player, ChatColor.AQUA + "----------------------------------------");

				mmsg(sender, "Your proposal has been made to " + utils.getPlayerListName(player));
//				+ ChatColor.AQUA + ", they have 5 minutes to reply.");

				return true;
			} else {
				if (args[0].equalsIgnoreCase("disable")) {
					marriageEnabled = false;
					mmsg(sender, "Dating Disabled");
					return true;
				}
				if (args[0].equalsIgnoreCase("enable")) {
					marriageEnabled = false;
					mmsg(sender, "Dating Disabled");
					return true;
				}
				mmsg(sender, "Consoles may not date!");
				return true;
			}
		} else {
			mmsg(sender, "Dating is not enabled");
			return true;
		}
	}
	
	public boolean dumpCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
		if (marriageEnabled) {
			String divorced = sql.getDatingPartner(sender.getName());
			if (divorced != null) { 
				divorce((Player) sender, divorced);
				
				return true;
			} else {
				mmsg(sender, "You are not dating anyone!");
				return true;
			}
		} else {
			mmsg(sender, "Dating is not enabled");
			return true;
		}
	}
	
	public boolean ignoreCommand(CommandSender sender, Command cmd, String cmdLabel, String[] args) {
		if (!(sender instanceof Player)) {
			log("Console's can't ignore");
			return false;
		}
		Player player = (Player) sender;
		if (args.length == 0) {
			msg(sender, "Toggle ignoring a player with: /ignore <Player>");
			return true;
		}
		String playerToIgnore = args[0];
		Player player2 = Bukkit.getPlayer(playerToIgnore);
		
		if (player2 != null && player2.getName().equals(player.getName())) {
			msg(sender, "You can't ignore yourself!");
		}
		
		ArrayList<String> alreadyIgnoring = sql.getIgnoredPlayers(player.getName());
		
		
		//Possibly REMOVING that player
		if (player2 != null && alreadyIgnoring.contains(player2.getName())) {
			sql.removeIgnoredPlayer(player.getName(), player2.getName());
			msg(player, "You are no longer ignoring " + player2.getName());
			return true;
		} else {
			for (String name : alreadyIgnoring) {
				if (name.toLowerCase().contains(playerToIgnore.toLowerCase())) {
					sql.removeIgnoredPlayer(player.getName(), name);
					msg(player, "You are no longer ignoring " + name);
					return true;
				}
			}
		}
		
		if (cmdLabel.equalsIgnoreCase("unignore")) {
			msg(player, "You are not ignoring anyone with that name.");
			return true;
		}
		
		if (player2 == null) {
			for (String playerName : globalPlayerList) {
				if (playerName.toLowerCase().contains(playerToIgnore.toLowerCase())) {
					sql.addIgnoredPlayer(player.getName(), playerName);
					msg(player, "You are now ignoring " + playerToIgnore);
					return true;
				}
			} 
			msg(player, playerToIgnore + " not found.");
			msg(player, "Please use proper caps for cross server ignoring.");
			return true;
		} else {
			sql.addIgnoredPlayer(player.getName(), player2.getName());
			msg(player, "You are now ignoring " + player2.getName());
			msg(player2, player.getName() + " is now ignoring you");
			return true;
		}
		
		
	}
	
	private void marry(Player player, Player spouse) {
		Bukkit.broadcastMessage(ChatColor.AQUA + "[" + ChatColor.RED + "Dating" + ChatColor.AQUA + "] " +  
				utils.getPlayerListName(player) + ChatColor.WHITE + " is now dating " + ChatColor.AQUA + utils.getPlayerListName(spouse) + ChatColor.WHITE + "!");
		sql.setDatingPartner(player.getName(), spouse.getName());
		sql.setDatingPartner(spouse.getName(), player.getName());
		marriageQueue.remove(player);
		marriageQueue.remove(spouse);
		
	}
	
	private void divorce(Player player, String spouse) {
		Bukkit.broadcastMessage(ChatColor.AQUA + "[" + ChatColor.RED + "Dating" + ChatColor.AQUA + "] " + ChatColor.RED + 
				player.getName() + " dumped " + spouse + "!");
		sql.setDatingPartner(player.getName(), null);
		sql.setDatingPartner(spouse, null);
		marriageQueue.remove(player);
		
	}
	
	private ArrayList<Player> getRecievers(Player player) {
		String channel = sql.getChannel(player.getName());
		if (channel == null)
			channel = "g";
		if (channel.equals("f")) {
			if (f_t != null) {
				ArrayList<Player> players = f_t.getFacPlayers(player);
				if (players.size() == 0) {
					channel = "g";
					sql.setChannel(player.getName(), "g");
					
				} else {
					return players;
				}
			} else {
				channel = "g";
				sql.setChannel(player.getName(), "g");
				
			}
		}
		if (channel.equals("t")) {
			if (f_t != null) {
				ArrayList<Player> players = f_t.getTownPlayers(player);
				if (players.size() == 0) {
					channel = "g";
					sql.setChannel(player.getName(), "g");
					
				} else {
					return players;
				}
			} else {
				channel = "g";
				sql.setChannel(player.getName(), "g");
				
			}
		}
		if (channel.equals("n")) {
			if (f_t != null) {
				ArrayList<Player> players = f_t.getNationPlayers(player);
				if (players.size() == 0) {
					channel = "g";
					sql.setChannel(player.getName(), "g");
					
				} else {
					return players;
				}
			} else {
				channel = "g";
				sql.setChannel(player.getName(), "g");
				
			}
		}
		if (channel.equals("s")) {
			ArrayList<Player> players = new ArrayList<Player>();
			for (Player p : Bukkit.getOnlinePlayers()) {
				if (p.hasPermission("ddchat.staffchat"))
					players.add(p);
			}
			return players;
		}
		ArrayList<Player> players = new ArrayList<Player>();
		for (Player rec : Bukkit.getOnlinePlayers()) {
			String c = sql.getChannel(rec.getName());
			if (sql.getBadProfile(player.getName()) && !rec.hasPermission("ddchat.getbad"))
				continue;
			if (sql.getIgnoredPlayers(rec.getName()).contains(player.getName()))
				continue;
			
			if (c == null)
				c = "g";
			if (c.equals("g") || c.equals("s")) {
				players.add(rec);
			}
			if (c.equals("w") || c.equals("f")) {
				if (rec.getWorld() == player.getWorld())
					players.add(rec);
			}
			if (c.equals("l")) {
				if (rec.getWorld() == player.getWorld())
					if (rec.getLocation().distance(player.getLocation()) < 100)
						players.add(rec);
			}
		}

		return players;
	}
	
	public void onBungeeMessageReceived(String channel, Player player, byte[] message) {
		DataInputStream in = new DataInputStream(new ByteArrayInputStream(message));
        String subchannel = null;
		try {
			subchannel = in.readUTF();
		} catch (IOException e) {
			log("Could not read plugin message");
			e.printStackTrace();
		}
        if (subchannel.equals("PlayerList")) {
        	try {
        		bungeePlayerListReceived(in.readUTF(), in.readUTF().split(", "), player);
        	} catch (Exception e) {}
        }
        if (subchannel.equals("DDCustomPlugin_Chat")) {
        	try {
        		short len = in.readShort();
        		byte[] msgbytes = new byte[len];
        		in.readFully(msgbytes);
        		
        		DataInputStream msgin = new DataInputStream(new ByteArrayInputStream(msgbytes));
        		String type = msgin.readUTF();
        		
        		if (type.equals("commandspy")) {
        			String command = msgin.readUTF();
        			for (Player p : Bukkit.getServer().getOnlinePlayers()) {
        				if (p.hasPermission("ddchat.commandsnoop") && !disabledSpys.contains(p) ) {
        					p.sendMessage(command);
        				}
        			}
        		}
        		if (type.equals("gchat")) {
        			String playerName = msgin.readUTF();
        			globalPlayerList.add(playerName);
        			String msg = msgin.readUTF();
        			Boolean isBad = msgin.readBoolean();
        			ArrayList<Player> players = new ArrayList<Player>();
        			for (Player rec : Bukkit.getOnlinePlayers()) {
        				String c = sql.getChannel(rec.getName());
        				if (isBad && !rec.hasPermission("ddchat.getbad")) {
        					continue;
        				}
        				if (c == null)
        					c = "g";
        				if (c.equals("g") || c.equals("s")) {
        					players.add(rec);
        				}
        				if (c.equals("w") || c.equals("f")) {
        					if (rec.getWorld() == player.getWorld())
        						players.add(rec);
        				}
        				if (c.equals("l")) {
        					if (rec.getWorld() == player.getWorld())
        						if (rec.getLocation().distance(player.getLocation()) < 100)
        							players.add(rec);
        				}
        			}
        			for (Player p : players) {
        				if (sql.getIgnoredPlayers(p.getName()).contains(playerName))
        					continue;
        				p.sendMessage(msg);
        			}
        		}
        		if (type.equals("schat")) {
        			String playerName = msgin.readUTF();
        			globalPlayerList.add(playerName);
        			String msg = msgin.readUTF();
        			for (Player rec : Bukkit.getOnlinePlayers()) {
        				if (rec.hasPermission("ddchat.staffchat"))
        					rec.sendMessage(msg);
        			}
        		}
        		if (type.equals("playermsg")) {
        			String sender = msgin.readUTF();
        			Player reciever = Bukkit.getPlayer(msgin.readUTF());
        			String msg = msgin.readUTF();
        			if (reciever != null) {
        				if (sql.getIgnoredPlayers(reciever.getName()).contains(removeFormattingCodes(sender)))
        					return;
        				reciever.sendMessage(sender + ChatColor.AQUA + " --" + ChatColor.BLUE + "> " + utils.getNamePrefix(reciever) + "You" + ChatColor.WHITE + ": " + msg);
        				lastMsg.put(reciever.getName(), removeFormattingCodes(sender));
        			}
        		}
        	} catch (Exception e) {}
        }
	}
	private String removeFormattingCodes(String input) {
		return input.replaceAll("§a", "").replaceAll("§b", "").replaceAll("§c", "").replaceAll("§d", "").replaceAll("§e", "").replaceAll("§f", "")
				.replaceAll("§0", "").replaceAll("§1", "").replaceAll("§2", "").replaceAll("§3", "").replaceAll("§4", "").replaceAll("§5", "")
				.replaceAll("§6", "").replaceAll("§7", "").replaceAll("§8", "").replaceAll("§9", "")
				.replaceAll("§k", "").replaceAll("§l", "").replaceAll("§m", "").replaceAll("§n", "").replaceAll("§o", "").replaceAll("§r", "");
	}
	@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
	public void onPlayerChatStart(AsyncPlayerChatEvent e) {
		e.setCancelled(true);
	}
	@EventHandler(priority = EventPriority.MONITOR)
	public void onPlayerChatEnd(AsyncPlayerChatEvent e) {
		if (plugin.fullMute.playerMuted(e.getPlayer().getName())) {
			if (plugin.fullMute.checkTime(e.getPlayer().getName())) {
				int left = (int)(sql.getMuteTime(e.getPlayer().getName()) - System.currentTimeMillis() / 1000);
				plugin.fullMute.msg(e.getPlayer(), "You are muted, and will stay muted for the remaining:");
				plugin.fullMute.msg(e.getPlayer(), plugin.fullMute.timeLeft(left));
				try {
					e.setCancelled(true);
					return;
				} catch (Exception ignored) {}
			}
		}
		if (e.getMessage().contains("connected with a") && e.getMessage().contains("using MineChat")) {
			return;
		}
		e.setCancelled(true);
		
		String channel = sql.getChannel(e.getPlayer().getName());
		if (channel == null) {
			channel = "g";
		}
		System.out.println(e.getPlayer().getName() + ": " + e.getMessage());
		sql.logChat(e.getPlayer(), e.getMessage(), channel);
		
		checkSpam(e.getPlayer(), e.getMessage());
		e.getPlayer().setPlayerListName(utils.getPlayerListName(e.getPlayer()));
		e.getPlayer().setDisplayName(utils.getDName(e.getPlayer()));
		sendMessage(convertMsg(e.getPlayer(), e.getMessage()), e.getPlayer());
	}
	@EventHandler (priority = EventPriority.LOW)
	public void onPlayerJoin(PlayerJoinEvent e) {
		if (f_t == null) {
			if (utils.getChannel(e.getPlayer()) == "f" || utils.getChannel(e.getPlayer()) == "t") {
				sql.setChannel(e.getPlayer().getName(), "g");
				
				msg(e.getPlayer(), "Channel set to " + utils.getChannelPrefix(e.getPlayer()) + "&oGlobal");
			}
		}
		
		
		e.getPlayer().setPlayerListName(utils.getPlayerListName(e.getPlayer()));
		e.getPlayer().setDisplayName(utils.getDName(e.getPlayer()));
		e.getPlayer().setCustomName(utils.getDName(e.getPlayer()));
		e.setJoinMessage("");
		Bukkit.broadcastMessage("     " + ChatColor.GREEN + "+ " + utils.getNamePrefix(e.getPlayer()) + e.getPlayer().getName());
	}
	
	Map<String, String> quitPlayers = new HashMap<String, String>();
	@EventHandler
	public void onPlayerQuit(PlayerQuitEvent e) {
		e.setQuitMessage(null);
		if (Bukkit.getServer().getOnlinePlayers().length > 0) {
			final ByteArrayOutputStream b = new ByteArrayOutputStream();
			DataOutputStream out = new DataOutputStream(b);
			try {
				out.writeUTF("PlayerList");
				out.writeUTF("ALL");
			} catch (Exception e2) {}
			quitPlayers.put(e.getPlayer().getName(), utils.getNamePrefix(e.getPlayer()) + e.getPlayer().getName());
			final Player player = Bukkit.getServer().getOnlinePlayers()[0];
			Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable(){
				@Override
				public void run() {
					player.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
				}
			}, 2);
		}
	}
	
	@EventHandler (priority = EventPriority.LOW)
	public void onPlayerKick(PlayerKickEvent e) {
		e.setLeaveMessage("     " + ChatColor.DARK_RED + "" + ChatColor.BOLD + "! " + utils.getNamePrefix(e.getPlayer()) + e.getPlayer().getName() + ChatColor.WHITE +  " - " + ChatColor.RED + "" + ChatColor.ITALIC + e.getReason());
		System.out.println("! " + e.getPlayer().getName() + " " + e.getReason());
//		for (RegisteredListener list : e.getHandlers().getRegisteredListeners()) {
//			log(list.getPlugin().toString());
//		}
//		e.setCancelled(true);
	}
	
	@EventHandler(priority = EventPriority.HIGHEST)
	public void onPlayerDeath(PlayerDeathEvent e) {
//		if (!(e.getEntity() instanceof Player))
//			return;
//		if (!(e instanceof PlayerDeathEvent))
//            return;
//		PlayerDeathEvent subEvent = (PlayerDeathEvent) e;
//		Player p = (Player)e.getEntity();
//		String msg = utils.getDName(p) + ChatColor.WHITE + " ";
//		DamageCause cause;
//		try {
//			cause = e.getEntity().getLastDamageCause().getCause();
//		} catch (Exception e1) {
//			msg += "died horribly";
//			subEvent.setDeathMessage(msg);
//			return;
//		}
//		if (cause == DamageCause.BLOCK_EXPLOSION)
//			msg += "instantaneously combusted.";
//		if (cause == DamageCause.CONTACT)
//			msg += "hugged a cactus.";
//		if (cause == DamageCause.CUSTOM)
//			msg += "died horribly.";
//		if (cause == DamageCause.DROWNING)
//			msg += "is sleeping with the fishes.";
//		if (cause == DamageCause.ENTITY_ATTACK)
//			if (p.getKiller() != null) {
//				msg = utils.getDName(p.getKiller()) + ChatColor.WHITE + " struck down " + utils.getDName(p);
//			} else {
//				String mob = lastEntity.getType().getName().toLowerCase();
//				if (mob.startsWith("a") || mob.startsWith("e") || mob.startsWith("i") || mob.startsWith("o") || mob.startsWith("u")) {
//					msg = "An " + mob + " ate " + utils.getDName(p) + ChatColor.WHITE + ".";
//				} else {
//					msg = "A " + mob + " ate " + utils.getDName(p) + ChatColor.WHITE + ".";
//				}
//			}
//		if (cause == DamageCause.ENTITY_EXPLOSION) {
//			String mob = lastEntity.getType().getName().toLowerCase();
//			if (mob.startsWith("a") || mob.startsWith("e") || mob.startsWith("i") || mob.startsWith("o") || mob.startsWith("u")) {
//				msg += "got too close to an " + lastEntity.getType().getName().toLowerCase() + ".";
//			} else {
//				msg += "got too close to a " + lastEntity.getType().getName().toLowerCase() + ".";
//			}
////			msg += "got too close to a " + lastEntity.getType().getName().toLowerCase();
//		}
//		if (cause == DamageCause.FALL)
//			msg += "fell from too high.";
//		if (cause == DamageCause.FALLING_BLOCK)
//			msg += " was under something heavy...";
//		if (cause == DamageCause.FIRE)
//			msg += "tried fighting fire with their face.";
//		if (cause == DamageCause.FIRE_TICK)
//			msg += "touched the hot-hot.";
//		if (cause == DamageCause.LAVA)
//			msg += "found their melting point in lava.";
//		if (cause == DamageCause.LIGHTNING)
//			msg += "was struck from heaven.";
//		if (cause == DamageCause.MAGIC)
//			msg += "got avadakadavra''d.";
//		if (cause == DamageCause.MELTING)
//			msg += "awkwardly melted...?";
//		if (cause == DamageCause.POISON)
//			msg += "overdoesed on drugs.";
//		if (cause == DamageCause.PROJECTILE) {
//			if (p.getKiller() != null) {
//				msg += "took an arrow to the knee from " + utils.getDName(p.getKiller()) + ".";
//			} else {
//				msg += "took an arrow to the knee.";
//			}
//		}
//		if (cause == DamageCause.STARVATION)
//			msg += "could't get to the kitchen in time.";
//		if (cause == DamageCause.SUFFOCATION)
//			msg = utils.getDName(p) + ChatColor.WHITE + " lacked their neccessary oxygen.";
//		if (cause == DamageCause.SUICIDE)
//			msg += "hated their life.";
//		if (cause == DamageCause.THORNS)
//			msg = utils.getDName(p.getKiller()) + ChatColor.WHITE + " took negative damage. Killing " + utils.getDName(p);
//		if (cause == DamageCause.VOID)
//			msg += "fell tried to fight the system.";
//		if (cause == DamageCause.WITHER)
//			msg += "took a witherball to seriously.";
//		subEvent.setDeathMessage(msg);
	}
	
	@EventHandler
	public void onCommandSent(final PlayerCommandPreprocessEvent e) {
		sql.logCommand(e.getPlayer(), e.getMessage());
		String msg = e.getMessage().toLowerCase();
		if (msg.startsWith("/f c ") || msg.equals("/f c") || msg.equals("/f chat")) {
			String c = sql.getChannel(e.getPlayer().getName());
			if (c != null && c.equals("f")) {
				sql.setChannel(e.getPlayer().getName(), "g");
				msg(e.getPlayer(), "Channel set to " + utils.getChannelPrefix(e.getPlayer()) + "&oGlobal");
			} else {
				sql.setChannel(e.getPlayer().getName(), "f");
				msg(e.getPlayer(), "Channel set to " + utils.getChannelPrefix(e.getPlayer()) + "&oFaction");
			}
			
			e.setCancelled(true);
		}
		if (msg.startsWith("/t c ") || msg.equals("/t c") || msg.equals("/t chat")) {
			String c = sql.getChannel(e.getPlayer().getName());
			if (c != null && c.equals("t")) {
				sql.setChannel(e.getPlayer().getName(), "g");
				msg(e.getPlayer(), "Channel set to " + utils.getChannelPrefix(e.getPlayer()) + "&oGlobal");
			} else {
				sql.setChannel(e.getPlayer().getName(), "t");
				msg(e.getPlayer(), "Channel set to " + utils.getChannelPrefix(e.getPlayer()) + "&oTown");
			}
			
			e.setCancelled(true);
		}
		if (msg.startsWith("/n c ") || msg.equals("/n c") || msg.equals("/n chat")) {
			String c = sql.getChannel(e.getPlayer().getName());
			if (c != null && c.equals("n")) {
				sql.setChannel(e.getPlayer().getName(), "g");
				msg(e.getPlayer(), "Channel set to " + utils.getChannelPrefix(e.getPlayer()) + "&oGlobal");
			} else {
				sql.setChannel(e.getPlayer().getName(), "n");
				msg(e.getPlayer(), "Channel set to " + utils.getChannelPrefix(e.getPlayer()) + "&oNation");
			}
			e.setCancelled(true);
		}
		if (msg.equalsIgnoreCase("/ac") || msg.equalsIgnoreCase("/a") || msg.toLowerCase().startsWith("/ac ") || msg.toLowerCase().startsWith("/a ")) {
			if (!e.getPlayer().hasPermission("ddchat.staffchat")) {
				msg(e.getPlayer(), "You don't have permission for staff chat.");
				e.setCancelled(true);
				return;
			}
			String c = sql.getChannel(e.getPlayer().getName());
			if (c != null && c.equals("s")) {
				sql.setChannel(e.getPlayer().getName(), "g");
				msg(e.getPlayer(), "Channel set to " + utils.getChannelPrefix(e.getPlayer()) + "&oGlobal");
			} else {
				sql.setChannel(e.getPlayer().getName(), "s");
				msg(e.getPlayer(), "Channel set to " + utils.getChannelPrefix(e.getPlayer()) + "&oStaff Chat");
			}
			e.setCancelled(true);
		}
		for (Player p : Bukkit.getServer().getOnlinePlayers()) {
			if (p.hasPermission("ddchat.commandsnoop") && !disabledSpys.contains(p) ) {
				p.sendMessage(utils.getPlayerListName(e.getPlayer()) + ChatColor.GRAY + ": " + e.getMessage());
			}
		}
		ByteArrayOutputStream b = new ByteArrayOutputStream();
		DataOutputStream out = new DataOutputStream(b);
		
		try {
			out.writeUTF("Forward");
			out.writeUTF("ALL");
			out.writeUTF("DDCustomPlugin_Chat");
			
			ByteArrayOutputStream msgbytes = new ByteArrayOutputStream();
			DataOutputStream msgout = new DataOutputStream(msgbytes);
			msgout.writeUTF("commandspy");
			msgout.writeUTF(utils.getPlayerListName(e.getPlayer()) + ChatColor.GRAY + ": " + e.getMessage()); // You can do anything you want with msgout
			
			out.writeShort(msgbytes.toByteArray().length);
			out.write(msgbytes.toByteArray());
		} catch (Exception e2) {}
		Player p = Bukkit.getOnlinePlayers()[0];
		
		p.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
		e.getPlayer().setPlayerListName(utils.getPlayerListName(e.getPlayer()));
		e.getPlayer().setDisplayName(utils.getDName(e.getPlayer()));
		e.getPlayer().setCustomName(utils.getDName(e.getPlayer()));
	}
	
	public void bungeePlayerListReceived(String server, String[] playerList, Player player) {
		
		updateGlobalPlayerList(playerList);
		ArrayList<String> playerList2 = new ArrayList<String>();
		for (String str : playerList) {
			playerList2.add(str);
		}
		
		
		for (String playerName : quitPlayers.keySet()) { // Loops through all players returned by Bungee
			if (playerList2.contains(playerName)) {
				Bukkit.getServer().broadcastMessage("     " + ChatColor.YELLOW + "~ " + quitPlayers.get(playerName));
			} else {
				Bukkit.getServer().broadcastMessage("     " + ChatColor.RED + "- " + quitPlayers.get(playerName));
			}
			quitPlayers.remove(playerName);
		}
	}
	
	public void updateGlobalPlayerList(String[] players) {
		globalPlayerList.clear();
		for (String data : players) {
			globalPlayerList.add(data);
		}
	}
	
	@EventHandler
	public void onPlayerKissEvent(PlayerInteractEntityEvent event) {
		final Player p = event.getPlayer();
		if (!utils.getDate(p).equals("")) {
			if (event.getRightClicked() instanceof Player) {
				if (sql.getDatingPartner(p.getName()) != null && sql.getDatingPartner(p.getName()).equals(((Player) event.getRightClicked()).getName())) {
					playWolfHearts(p.getLocation());
					playWolfHearts(event.getRightClicked().getLocation());
				}
			}
		}
	}
	
	public void playWolfHearts(Location loc) {
        World world = loc.getWorld();
        Wolf wo = (Wolf) world.spawn(loc, Wolf.class);
        wo.remove();
        net.minecraft.server.v1_6_R3.World nmsWorld = ((CraftWorld) world).getHandle();
        net.minecraft.server.v1_6_R3.EntityWolf nmsWolf = (EntityWolf) ((CraftEntity) wo).getHandle();
        nmsWorld.broadcastEntityEffect(nmsWolf, (byte) 7);
    }

	private void sendMessage(String msg, Player player) {
		String world = player.getWorld().getName();
		
		if (world.equals("Survival")) {
			for (Player p : getRecievers(player)) {
				p.sendMessage(ChatColor.translateAlternateColorCodes('&', utils.getFaction(player, p)) + msg);
			}
		} else if (world.equals("TownWorld")) {
			for (Player p : getRecievers(player)) {
				p.sendMessage(ChatColor.translateAlternateColorCodes('&', utils.getTown(player)) + msg);
			}
		} else {
			for (Player p : getRecievers(player)) {
				p.sendMessage(msg);
			}
		}
		String channel = sql.getChannel(player.getName());
		if (channel == null)
			channel = "g";
		if (channel.equals("g") || channel.equals("s")) {
			ByteArrayOutputStream b = new ByteArrayOutputStream();
			DataOutputStream out = new DataOutputStream(b);
			 
			try {
				out.writeUTF("Forward");
				out.writeUTF("ALL");
				out.writeUTF("DDCustomPlugin_Chat");
				
				ByteArrayOutputStream msgbytes = new ByteArrayOutputStream();
				DataOutputStream msgout = new DataOutputStream(msgbytes);
				msgout.writeUTF(channel + "chat");
				msgout.writeUTF(player.getName());
				msgout.writeUTF(msg);
				msgout.writeBoolean(sql.getBadProfile(player.getName()));
				 
				out.writeShort(msgbytes.toByteArray().length);
				out.write(msgbytes.toByteArray());
			} catch (Exception e2) {}
			player.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
		}
	}
	
	private void msg(CommandSender sender, String msg) {
		if (sender instanceof Player) {
			((Player) sender).sendMessage(ChatColor.RESET + "[" + ChatColor.RED + "MSG" + ChatColor.WHITE + "] " + ChatColor.AQUA + ChatColor.translateAlternateColorCodes('&', msg));
		} else {
			log(msg);
		}
	}
	private void mmsg(CommandSender sender, String msg) {
		if (sender instanceof Player) {
			((Player) sender).sendMessage(ChatColor.AQUA + "[" + ChatColor.RED + "Dating" + ChatColor.AQUA + "] " + ChatColor.AQUA + ChatColor.translateAlternateColorCodes('&', msg));
		} else {
			log(msg);
		}
	}
	private boolean setupPermissions() {
		RegisteredServiceProvider<Permission> rsp = plugin.getServer()
				.getServicesManager().getRegistration(Permission.class);
		perms = rsp.getProvider();
		return perms != null;
	}

	public void log(String info) {
		plugin.getLogger().info("<Chat> " + info);
	}
} public class ChatPrefix {
	private CustomPlugin plugin;

	private ChatSQL sql;
	
	public ChatPrefix(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	@SuppressWarnings("static-access")
	public void enable() {
		sql = plugin.chat.sql;
		log("Enabled");
	}

	public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
		if (!(sender instanceof Player)) {
			if (args.length > 1){
				Player otherplayer = Bukkit.getPlayer(args[0]);
				if (otherplayer != null){
					args[0] = otherplayer.getName();
					String prefix = args[1];
					for (int x = 2; x < args.length; x++){
						prefix = prefix + " " + args[x];
					}
					sql.setPrefix(args[0], prefix);
					log(otherplayer.getName() + "'s name has been formatted to: " + prefix);
				} else {
					log(args[0] + " not found");
				}
			} else {
				log("Try: /fullprefix [Player] [Name Format]");
			}
			return true;
		}
		Player player = (Player)sender;
		if (player.hasPermission("mchat.prefix") || player.isOp()) { // VIP User
			if (args.length != 0) { // Must have arguments
				if (player.hasPermission("mchat.prefix.admin") || player.isOp()) {
					Player otherplayer = Bukkit.getPlayer(args[0]);
					if (otherplayer != null && args.length != 1){ //Administrator changes someone's name
						args[0] = otherplayer.getName();
						if (otherplayer.hasPermission("mchat.prefix")) {
							String prefix = args[1];
							for (int x = 2; x < args.length; x++){
								prefix = prefix + " " + args[x];
							}
							if (cutLength(prefix) <= 10) {
								sql.setPrefix(args[0], removeFormattingCodes("&e<" + prefix + "&e> ") + "%name%");
								player.sendMessage(ChatColor.GREEN + args[0] + "'s name has been formatted to:");
								player.sendMessage(prefixWithFormatting("&e<" + prefix + "&e> ") + args[0]);
								otherplayer.sendMessage(ChatColor.GREEN + "Your name has been formatted to:");
								otherplayer.sendMessage(prefixWithFormatting("&e<" + prefix + "&e> ") + args[0] + " by " + player.getName());
								log(player.getName() + " changed " + args[0] + "'s name to be formatted: " + removeFormattingCodes("&e<" + prefix + "&e> ") + otherplayer.getPlayerListName());
								//[Administrator] changed [Player]'s name to be formatted <[Prefix]&6> [Player]
							} else {
								player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "Prefix too long.");
							}
						} else {
							player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + args[0] + " lacks permission for a prefix.");
						}
					} else { //Administrator changes his own name
						String prefix = args[0];
						for (int x = 1; x < args.length; x++){
							prefix = prefix + " " + args[x];
						}
						if (cutLength(prefix) <= 10) {
							sql.setPrefix(player.getName(), removeFormattingCodes("&e<" + prefix + "&e> ") + "%name%");
							player.sendMessage(ChatColor.GREEN + "Your name has been formatted to:");
							player.sendMessage(prefixWithFormatting("&e<" + prefix + "&e> ") + player.getPlayerListName());
							log(player.getName() + " changed their name to be formatted: " + removeFormattingCodes("&e<" + prefix + "&e> ") + player.getPlayerListName());
							//[AdministratorUsername] changed his name to be formatted: <[Prefix]&c> [AdministratorUsername]
						} else {
							player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "Prefix too long.");
						}
					}
				} else {
					//Regular VIP user changing his name:
					String prefix = args[0];
					for (int x = 1; x < args.length; x++){
						prefix = prefix + " " + args[x];
					}
					if (cutLength(prefix) <= 10) {
						sql.setPrefix(player.getName(), removeFormattingCodes("&e<" + prefix + "&e> ") + "%name%");
						player.sendMessage(ChatColor.GREEN + "Your name has been formatted to:");
						player.sendMessage(prefixWithFormatting("&e<" + prefix + "&e> ") + player.getPlayerListName());
						log(player.getName() + " changed their name to be formatted: " + removeFormattingCodes("&e<" + prefix + "&e> ") + player.getPlayerListName());
						//[Player] changed his name to be formatted: <[Prefix]&6> [Player]
					} else {
						player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "Prefix too long.");
					}
				}
			} else { //No arguments???? Help Message
				player.sendMessage(ChatColor.YELLOW + "To change your perfix:");
				player.sendMessage(ChatColor.AQUA + "/prefix [" + ChatColor.GREEN + "Prefix" + ChatColor.AQUA+ "]");
				player.sendMessage(ChatColor.YELLOW + "To delete your perfix:");
				player.sendMessage(ChatColor.AQUA + "/delprefix");
				if (player.hasPermission("mchat.prefix.admin") || player.isOp()) { //Extra Administrator Help
					player.sendMessage(ChatColor.ITALIC + "-=-=-=-=-=-= Admin Commands =-=-=-=-=-=-");
					player.sendMessage(ChatColor.GOLD + "To change another player's prefix:");
					player.sendMessage(ChatColor.AQUA + "/prefix [" + ChatColor.GREEN + "Player" + ChatColor.AQUA + "] [" + ChatColor.GREEN + "Prefix" + ChatColor.AQUA+ "]");
					player.sendMessage(ChatColor.GOLD + "To delete another player's perfix:");
					player.sendMessage(ChatColor.AQUA + "/delprefix [" + ChatColor.GREEN + "Player" + ChatColor.AQUA+ "]");
					player.sendMessage(ChatColor.GOLD + "Reformat your name:");
					player.sendMessage(ChatColor.AQUA + "/fullprefix [" + ChatColor.GREEN + "Name Format" + ChatColor.AQUA + "]");
					player.sendMessage(ChatColor.GOLD + "Reformat another player's name:");
					player.sendMessage(ChatColor.AQUA + "/fullprefix [" + ChatColor.GREEN + "Player" + ChatColor.AQUA + "] [" + ChatColor.GREEN + "Name Format" + ChatColor.AQUA + "]");
					player.sendMessage(ChatColor.GOLD + "[Player] must be the full, case sensitive player's name");
				}
			}
		} else {
			player.sendMessage(ChatColor.RED + "You can't change you Prefix! You need to be a Elite status or higher!");
		}
		return true;
	}

	public boolean delPrefix(CommandSender sender, Command cmd, String label, String[] args) {
		if (sender instanceof Player) {
			Player player = (Player)sender;
			if (player.hasPermission("mchat.prefix") || player.isOp()) { // VIP User
				if (player.hasPermission("mchat.prefix.admin") || player.isOp()) { // Administrator
					if (args.length != 0) {
						Player otherplayer = Bukkit.getPlayer(args[0]);
						if (otherplayer != null) {
							args[0] = otherplayer.getName();
						}
						if (sql.getPrefix(args[0]) == null) {
							player.sendMessage(ChatColor.GREEN + args[0] + " never had a prefix");
						} else {
							sql.setPrefix(args[0], null);
							player.sendMessage(ChatColor.GREEN + args[0] + "'s prefix has been removed.");
							if (otherplayer != null){
								otherplayer.sendMessage(ChatColor.GREEN + "Your prefix has been removed by " + player.getName());
							}
							log(player.getName() + " removed " + args[0] + "'s prefix");
						}
					} else { // Administrator resetting his own prefix
						sql.setPrefix(player.getName(), null);
						player.sendMessage(ChatColor.GREEN + "Your prefix has been removed.");
						log(player.getName() + " removed their prefix");
					}
				} else { // Regular VIP
					sql.setPrefix(player.getName(), null);
					player.sendMessage(ChatColor.GREEN + "Your prefix has been removed.");
				}
			} else {
				player.sendMessage(ChatColor.RED + "You can't change you Prefix! You need to be a Sponsor, Premium or Boss!");
			}
		} else { //Console is executing
			if (args.length != 0) {
				sql.setPrefix(args[0], null);
				log(ChatColor.GREEN + args[0] + "'s prefix has been removed.");
			} else { // Administrator resetting his own prefix
				log("Please provide a username to reset");
			}				
		}
		return true;
	}

	public boolean fullPrefix(CommandSender sender, Command cmd, String label, String[] args) {
		if (sender instanceof Player) {
			Player player = (Player)sender;
			if (player.hasPermission("mchat.prefix.admin") || player.isOp()){
				if (args.length != 0){
					Player otherplayer = Bukkit.getPlayer(args[0]);
					if (otherplayer != null && args.length != 1){
						args[0] = otherplayer.getName();
						String prefix = args[1];
						for (int x = 2; x < args.length; x++){
							prefix = prefix + " " + args[x];
						}
						sql.setPrefix(args[0], prefix);
						player.sendMessage(ChatColor.GREEN + otherplayer.getName() + "'s name has been formatted to: " + prefix);
						log(args[0] + "'s name has been formatted to: " + prefix);
					} else { //Changing his own name
						String prefix = args[0];
						for (int x = 1; x < args.length; x++){
							prefix = prefix + " " + args[x];
						}
						sql.setPrefix(player.getName(), prefix);
						player.sendMessage(ChatColor.GREEN + "Your name has been formatted to: " + prefix);
						log(player.getName() + "'s name has been formatted to: " + prefix);
					}
				} else {
					player.sendMessage(ChatColor.GOLD + "Reformat your name:");
					player.sendMessage(ChatColor.AQUA + "/fullprefix [" + ChatColor.GREEN + "Name Format" + ChatColor.AQUA + "]");
					player.sendMessage(ChatColor.GOLD + "Reformat another player's name:");
					player.sendMessage(ChatColor.AQUA + "/fullprefix [" + ChatColor.GREEN + "Player" + ChatColor.AQUA + "] [" + ChatColor.GREEN + "Name Format" + ChatColor.AQUA + "]");
				}
			} else {
				if (player.hasPermission("mchat.prefix")) {
					player.sendMessage(ChatColor.RED + "You can't change you Name! Only your prefix with /prefix");
				} else {
					player.sendMessage(ChatColor.RED + "You must be an administrator to use this command.");
				}
			}
		}
		return true;
	}

	public String prefixWithFormatting(String input){	
		return input.replaceAll("&a", ChatColor.GREEN + "&a").replaceAll("&b", ChatColor.AQUA + "&b").replaceAll("&c", ChatColor.RED + "&c").replaceAll("&d", ChatColor.LIGHT_PURPLE + "&d").replaceAll("&e", ChatColor.YELLOW + "&e").replaceAll("&f", ChatColor.WHITE + "&f")
				.replaceAll("&0", ChatColor.BLACK + "&0").replaceAll("&1", ChatColor.DARK_BLUE + "&1").replaceAll("&2", ChatColor.DARK_GREEN + "&2").replaceAll("&3", ChatColor.DARK_AQUA + "&3").replaceAll("&4", ChatColor.DARK_RED + "&4").replaceAll("&5", ChatColor.DARK_PURPLE +  "&5")
				.replaceAll("&6", ChatColor.GOLD + "&6").replaceAll("&7", ChatColor.GRAY + "&7").replaceAll("&8", ChatColor.DARK_GRAY + "&8").replaceAll("&9", ChatColor.BLUE + "&9")
				.replaceAll("&k", "").replaceAll("&l", "").replaceAll("&m", "").replaceAll("&n", "").replaceAll("&o", "").replaceAll("&r", "");
	}

	public String removeFormattingCodes(String input){
		return input.replaceAll("&k", "").replaceAll("&l", "").replaceAll("&m", "").replaceAll("&n", "").replaceAll("&o", "").replaceAll("&r", "");
	}

	public int cutLength(String prefix){
		return removeColorCodes(prefix).length();
	}

	public String removeColorCodes(String input){
		return input.replaceAll("&a", "").replaceAll("&b", "").replaceAll("&c", "").replaceAll("&d", "").replaceAll("&e", "").replaceAll("&f", "")
				.replaceAll("&0", "").replaceAll("&1", "").replaceAll("&2", "").replaceAll("&3", "").replaceAll("&4", "").replaceAll("&5", "")
				.replaceAll("&6", "").replaceAll("&7", "").replaceAll("&8", "").replaceAll("&9", "")
				.replaceAll("&k", "").replaceAll("&l", "").replaceAll("&m", "").replaceAll("&n", "").replaceAll("&o", "").replaceAll("&r", "");
	}

	public void log(String info) {
		plugin.getLogger().info("<ChatPrefix> " + info);
	}
} public class ColorArmor {
	private CustomPlugin plugin;
	
	public ColorArmor(CustomPlugin plugin) {
		this.plugin = plugin;
	}
	
	private int red = 255, green = 0, blue = 0;
	public int add = 20;
	private int gaining = 1; //1=RED, 2=YELLOW, 2=GREEN, 3=AQUA, 4=BLUE, 5=PURPLE
	private Color color = Color.fromRGB(red, green, blue);

	@SuppressWarnings("deprecation")
	public void enable() {
//		plugin.getServer().getPluginManager().registerEvents(this, plugin);
		log("Enabled");
		plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
			@Override
			public void run() {
				changeColors();
				for (Player player : Bukkit.getOnlinePlayers()) {
					if (player.hasPermission("customplugin.colorarmor")) {
						apply(player);
					}
				}
			}
		}, 5, 5);
	}
	
	private void changeColors() {
		if (gaining == 1) {
			if (red == 255 && green == 0 && blue == 0) {
				gaining = 2;
				return;
			}
			red += add;
			green -= add;
			blue -= add;
		}
		if (gaining == 2) {
			if (red == 255 && green == 255 && blue == 0) {
				gaining = 3;
				return;
			}
			red += add;
			green += add;
			blue -= add;
		}
		if (gaining == 3) {
			if (red == 0 && green == 255 && blue == 0) {
				gaining = 4;
				return;
			}
			red -= add;
			green += add;
			blue -= add;
		}
		if (gaining == 4) {
			if (red == 0 && green == 255 && blue == 255) {
				gaining = 5;
				return;
			}
			red -= add;
			green += add;
			blue += add;
		}
		if (gaining == 5) {
			if (red == 0 && green == 0 && blue == 255) {
				gaining = 6;
				return;
			}
			red -= add;
			green -= add;
			blue += add;
		}
		if (gaining == 6) {
			if (red == 255 && green == 0 && blue == 255) {
				gaining = 1;
				return;
			}
			red += add;
			green -= add;
			blue += add;
		}
		if (red > 255) {
			red = 255;
		}
		if (red < 0) {
			red = 0;
		}
		if (green > 255) {
			green = 255;
		}
		if (green < 0) {
			green = 0;
		}
		if (blue > 255) {
			blue = 255;
		}
		if (blue < 0) {
			blue = 0;
		}
		color = Color.fromRGB(red, green, blue);
	}
	
	private ItemStack setColor(ItemStack is) {
		LeatherArmorMeta im = (LeatherArmorMeta) is.getItemMeta();
		im.setColor(color);
		is.setItemMeta(im);
		return is;
	}
	
	private void apply(Player player) {
		if (player == null)
			return;
		ItemStack helmet = player.getInventory().getHelmet();
		ItemStack chestplate = player.getInventory().getChestplate();
		ItemStack leggings = player.getInventory().getLeggings();
		ItemStack boots = player.getInventory().getBoots();
		if (helmet == null || !helmet.getType().equals(Material.LEATHER_HELMET))
			return;
		if (chestplate == null || !chestplate.getType().equals(Material.LEATHER_CHESTPLATE))
			return;
		if (leggings == null || !leggings.getType().equals(Material.LEATHER_LEGGINGS))
			return;
		if (boots == null || !boots.getType().equals(Material.LEATHER_BOOTS))
			return;
		player.getInventory().setHelmet(setColor(helmet));
		player.getInventory().setChestplate(setColor(chestplate));
		player.getInventory().setLeggings(setColor(leggings));
		player.getInventory().setBoots(setColor(boots));
	}

	private void log(String info) {
		plugin.getLogger().info("<ColorArmor> " + info);
	}
} public class CommandModifier {
	private CustomPlugin plugin;

	public CommandModifier(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	public void onCommandPreprocess(PlayerCommandPreprocessEvent event)
	{
		Player player = event.getPlayer();
		String command = event.getMessage().toLowerCase();
		if ((command.startsWith("/sg") || event.getMessage().toLowerCase().startsWith("/survivalgames")) && !event.getPlayer().getWorld().getName().equals("EventWorld")) {
			Bukkit.dispatchCommand(player, "warp sg");
			event.setCancelled(true);
		}
		
		if (command.startsWith("/tempban ")) {
			if (player.hasPermission("customplugin.ban")) {
				String[] args = event.getMessage().split(" ");
				String arg = args[2];
				long time = getTimeStamp(arg);
				if (time == -3) {
					event.setMessage("/tempban " + args[1] + " 5h");
					event.getPlayer().sendMessage(ChatColor.GREEN + "Mods can only ban up to 5 hours.");
				}
			}
		}
		
		if (command.startsWith("/auc start") || command.startsWith("/auction start")) {
			String msg = event.getMessage();
			if (msg.split(" ").length == 3 && event.getPlayer().getItemInHand() != null) {
				event.setMessage("/auc start " + event.getPlayer().getItemInHand().getAmount() + " " + msg.split(" ")[2] + " 10");
			}
		}
		
		if (command.equalsIgnoreCase("/pl") || command.equalsIgnoreCase("/plugins")) {
			event.setMessage("/plugman list");
		}
		
		if (command.equalsIgnoreCase("/hns")) {
			event.setMessage("/has");
		}
		
		if (command.startsWith("/hns") || command.startsWith("/hidenseek") || command.startsWith("/bh") || command.startsWith("/hideandseek") || command.startsWith("/has") || command.startsWith("/ph") || command.startsWith("/blockhunt") || command.startsWith("/prophunt")) {
			if (!command.contains(" ")) {
				event.setCancelled(true);
				player.sendMessage(ChatColor.BLUE + "_______.[" + ChatColor.YELLOW + " HideNSeek " + ChatColor.BLUE + "]._______");
				player.sendMessage(ChatColor.AQUA + "Welcome to HideNSeek");
				player.sendMessage(ChatColor.AQUA + "Type " + ChatColor.YELLOW + "/hns join" + ChatColor.AQUA + " to join the fun!");
				player.sendMessage(ChatColor.AQUA + "Type " + ChatColor.YELLOW + "/hns leave" + ChatColor.AQUA + " if you need to go.");
				player.sendMessage(ChatColor.AQUA + "Type " + ChatColor.YELLOW + "/hns shop" + ChatColor.AQUA + " to check out the shop.");
				player.sendMessage(ChatColor.BLUE + "_______.[" + ChatColor.YELLOW + " HideNSeek " + ChatColor.BLUE + "]._______");
			}
			if (command.contains("j")) {
				event.setMessage("/has join Buried");
			}
			if (command.contains("l")) {
				event.setCancelled(true);
				Bukkit.dispatchCommand(event.getPlayer(), "has leave");
			}
			if (command.contains("shop")) {
				event.setMessage("/has shop");
			}
		}
		
		if (command.startsWith("/tnt ")) {
			event.setCancelled(true);
		}
		
		if (command.startsWith("/baltop") || command.startsWith("/balancetop")) {
			event.setMessage("/money top");
		}
		
		if (command.startsWith("/bal")) {
			event.setMessage("/money");
		}
		
		if (command.startsWith("/listhomes")) {
			event.setMessage("/homes");
		}
		
		if (command.startsWith("/warp ew") || command.startsWith("/warp event")) {
//			event.setMessage("/server events");
			event.setCancelled(true);
			tpServer(player, "events");
		} else
		
		if (command.startsWith("/warp sb") || command.startsWith("/warp sky")) {
//			event.setMessage("/server skyblock");
			event.setCancelled(true);
			tpServer(player, "skyblock");
		} else 
		
		if (command.startsWith("/warp ds") || command.startsWith("/warp dest")) {
//			event.setMessage("/server destruction");
			event.setCancelled(true);
			tpServer(player, "destruction");
		} else
		
		if (command.startsWith("/warp b") || command.startsWith("/warp build")) {
//			event.setMessage("/server build");
			event.setCancelled(true);
			tpServer(player, "creative");
		} else
		
		if (command.startsWith("/warp sv") || command.startsWith("/warp surviv")) {
//			event.setMessage("/server survival");
//			event.setCancelled(true);
			tpServer(player, "survival");
		} else
			
		if (command.startsWith("/warp ")) {
			event.setCancelled(true);
			String warpName = command.split(" ")[1];
			String server = "";
			String world = "";
			String x = "";
			String y = "";
			String z = "";
			String yaw = "";
			String pitch = "";
			ResultSet result = null;
			Connection con = null;
			try {
				con = SQL.getConnection();

				Statement st = (Statement) con.createStatement(); 
				result = st.executeQuery("SELECT * FROM `BungeeWarps` WHERE `warpname`='" + warpName.toLowerCase() + "';");
				
				while (result.next()) {
					server = result.getString("server");
					world = result.getString("world");
					x = result.getString("x");
					y = result.getString("y");
					z = result.getString("z");
					yaw = result.getString("yaw");
					pitch = result.getString("pitch");
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
			if (server.equals("")) {
				player.sendMessage(ChatColor.RED + "That warp does not exist");
			}
			if (server.equals(plugin.detectedServer())) {
				player.teleport(new Location(Bukkit.getWorld(world), Double.parseDouble(x), Double.parseDouble(y), Double.parseDouble(z), Float.parseFloat(yaw), Float.parseFloat(pitch)));
			} else {
				ByteArrayOutputStream b = new ByteArrayOutputStream();
				DataOutputStream out = new DataOutputStream(b);
				
				try {
					
					out.writeUTF("Forward");
					out.writeUTF("ALL");
					out.writeUTF("DDCustomPlugin_Homes");

					ByteArrayOutputStream msgbytes = new ByteArrayOutputStream();
					DataOutputStream msgout = new DataOutputStream(msgbytes);
					msgout.writeUTF(player.getName());
					msgout.writeUTF(world + ";" + x + ";" + y + ";" + z + ";" + pitch + ";" + yaw);

					out.writeShort(msgbytes.toByteArray().length);
					out.write(msgbytes.toByteArray());

					player.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
					
					b = new ByteArrayOutputStream();
					out = new DataOutputStream(b);

					out.writeUTF("Connect");
					out.writeUTF(server);
				
				} catch (IOException e) {
					e.printStackTrace();
				}
				
				player.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
			}
		}
		
		if (event.getPlayer().hasPermission("permissions.manage")) {
			if (event.getMessage().startsWith("/promote "))
				BungeeGlobalCommand.sendCommand("pex reload");
			else if (event.getMessage().startsWith("/demote "))
				BungeeGlobalCommand.sendCommand("pex reload");
			else if (event.getMessage().startsWith("/pex user "))
				BungeeGlobalCommand.sendCommand("pex reload");
		}
		if (command.equalsIgnoreCase("/spawn")) {
			event.setMessage("/worldspawn");
		}
		if (command.equalsIgnoreCase("/hub")) {
			event.setMessage("/globalspawn");
		}
	}
	
	private long getTimeStamp(String time) {
		long timestamp = System.currentTimeMillis() / 1000;
		String unit = time.substring(time.length() - 1, time.length());
		String input = time.substring(0, time.length() - 1);
		int add = 0;
		try {
			add = Integer.parseInt(input);
		} catch (Exception e) {
			return -1;
		}
		if (unit.equalsIgnoreCase("s")) {
			timestamp += add;
		} else if (unit.equalsIgnoreCase("m")) {
			timestamp += add*60;
		} else if (unit.equalsIgnoreCase("h")) {
			timestamp += add*60*60;
		} else if (unit.equalsIgnoreCase("d")) {
			timestamp += add*60*60*24;
		} else {
			return -2;
		}
		if (timestamp - System.currentTimeMillis() / 1000 > 60*60*5)
			return -3;
		return timestamp;
	}
	
	public void tpServer(Player player, String server) {
		ByteArrayOutputStream b = new ByteArrayOutputStream();
		DataOutputStream out = new DataOutputStream(b);

		try {
			out.writeUTF("Connect");
			out.writeUTF(server);
		} catch (IOException e) {
			e.printStackTrace();
		} 
		player.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
	}

	public void log(String info) {
		plugin.getLogger().info("<CommandModifier> " + info);
	}
} public class CrashPlayer {

	private CustomPlugin plugin;

	public CrashPlayer(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	public boolean onCommand(CommandSender sender, String args[]) {
			if (sender instanceof Player) {
				if (!((Player) sender).hasPermission("customplugin.crash")) {
					sender.sendMessage("Unknown command. Type \"/help\" for help.");
					return true;
				}
				if (args.length < 1) {
					sender.sendMessage(ChatColor.RED + "/crash [player]");
					return true;
				}
				if (Bukkit.getPlayer(args[0]) == null) {
					sender.sendMessage(ChatColor.RED + args[0] + " not found.");
					return false;
				}
				Player player = Bukkit.getPlayer(args[0]);
				Chest chest = null;
				Inventory inv = Bukkit.createInventory((InventoryHolder) chest, 360, "GET CRASHED");
				if (!player.hasPermission("customplugin.crash") || ((Player) sender).isOp()) {
					player.openInventory(inv);
					for (Player on : Bukkit.getOnlinePlayers()) {
						if (on.hasPermission("ddchat.staffchat")) {
							if (sender instanceof Player && on == (Player) sender)
								on.sendMessage(ChatColor.RED + player.getName() + " now crashing " + ChatColor.DARK_RED + ">:)");
							else {
								if (sender instanceof Player) 
									on.sendMessage(ChatColor.RED + player.getName() + " now crashing by: " + ChatColor.DARK_RED + sender.getName());
							}
						}
					}
					log(player.getName() + " now crashing");
					return true;
				} else {
					sender.sendMessage(ChatColor.RED + args[0] + " is not a crashable player");
					return true;
				}
			} else {
				if (args.length < 1)
					return true;
				if (Bukkit.getPlayer(args[0]) == null)
					return false;
				Player player = Bukkit.getPlayer(args[0]);
				Chest chest = null;
				Inventory inv = Bukkit.createInventory((InventoryHolder) chest, 360, "Lol, get crashed");
				if (!player.hasPermission("customplugin.crash"))
					player.openInventory(inv);
			}
			return true;
		}

	public void log(String info) {
		plugin.getLogger().info("<CrashPlayer> " + info);
	}
} public class CustomRecipies {
	private CustomPlugin plugin;

	public CustomRecipies(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("FleshToLeather:");
		plugin.getServer().addRecipe(new FurnaceRecipe(new ItemStack(Material.LEATHER), Material.ROTTEN_FLESH));
		log("Enabled");
	}

	public void log(String info) {
		plugin.getLogger().info("<CustomRecipies> " + info);
	}
} public class FullMute {
	private CustomPlugin plugin;
	
	public FullMute(CustomPlugin plugin) {
		this.plugin = plugin;
	}
	
	ChatSQL sql;
	
	@SuppressWarnings("static-access")
	public void enable() {
//		plugin.getServer().getPluginManager().registerEvents(this, plugin);
		sql = plugin.chat.sql;
		blockedCommands.add("/me");
		log("Enabled");
	}
	
	public ArrayList<String> blockedCommands = new ArrayList<String>();
	
//	@SuppressWarnings("unchecked")
//	public void onEnable() {
//		plugin.getServer().getPluginManager().registerEvents(this, plugin);
//		saveMuted();
//		try {
//			log("Loading Muted Players...");
//			reloadMuted();
//		} catch (Exception e) {
//			log("Could not load the config file!!");
//		}
//		blockedCommands = (ArrayList<String>)getMuteTime().getList("blocked-commands");
//
//		log("FullMute Plugin Enabled");
//	}
//
//	public void onDisable() {
//		log("FullMute Plugin Disabled");
//	}

	@SuppressWarnings("static-access")
	public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
		if (label.equalsIgnoreCase("mute")) {
			if (sender instanceof Player){
				Player player = (Player)sender;
				if (!player.hasPermission("fullmute.mute")){
					msg(player, "Insufficient Permissions");
					return true;
				}
			}

			if (args.length >= 1) {
				if (args.length >= 2) {
					mute(sender, args[0], args[1], false);
				} else {
					mute(sender, args[0], null, false);	
				}
			} else {
				msg(sender, "Try /mute [Player]");
			}
			return true;

		} else if (label.equalsIgnoreCase("me")) {
			if (sender instanceof Player){
				Player player = (Player)sender;
				if (player.hasPermission("mchat.me")) {
					if (args.length != 0) {
						String meMsg = args[0];
						for (int x = 1; x < args.length; x++) {
							meMsg += " " + args[x];
						}
						meMsg = plugin.chat.utils.removeCussWords(meMsg, true, player, !player.hasPermission("ddchat.censorbypass"), ChatColor.YELLOW + "");
						if (player.hasPermission("ddchat.color")) {
							meMsg = ChatColor.translateAlternateColorCodes('&', meMsg); 
						} else {
							meMsg = plugin.chat.utils.changeCussColors(meMsg);
						}
						if (!player.hasPermission("ddchat.caps"))
							meMsg = plugin.chat.utils.removeCAPS(meMsg);
						plugin.getServer().broadcastMessage(ChatColor.DARK_RED + "*" + player.getPlayerListName().substring(0, 2) + player.getName() + ChatColor.YELLOW + " " + meMsg);
					} else {
						player.sendMessage(ChatColor.RED + "Correct usage: /me <message>");
					}
				} else {
					player.sendMessage(ChatColor.RED + "You do not have permission to use /me");
				}
			} else {
				msg(sender, "You just try to do /me console :P YOU CAN'T");
			}
			return true;
		}
		return false;
	}

	public void mute(CommandSender sender, String player, String time, boolean def) {
		Player realPlayer = Bukkit.getPlayer(player);
		if (playerMuted(player)) {
			sql.setMuteTime(realPlayer.getName(), 0);
			if (realPlayer != null) 
				msg(realPlayer, "You are now free to talk.");
			msg(sender, player + " successfully unmuted.");
			return;
		}
		
		if (realPlayer == null) {
			msg(sender, "Player Not Found!");
			return;
		}
		player = realPlayer.getName();
		
		if (time == null) {
			if (!playerMuted(player)) {
				for (Player on : Bukkit.getOnlinePlayers()) {
					if (on.hasPermission("fullmute.mute")) {
						if (sender instanceof Player && on == (Player) sender)
							msg(on, player + " muted for the default 5 minutes");
						else {
							if (sender instanceof Player) 
								msg(on, player + " muted for the default 5 minutes by: " + ((Player) sender).getName());
							else
								msg(on, player + " muted for the default 5 minutes by: Console");	
						}
					}
				}
				if (!(sender instanceof Player))
					msg(sender, player + " muted for the default 5 minutes");
				msg(realPlayer, "You have been muted for 5 minutes.");
				msg(sender, "To specify a time, type /mute <player> <time>s,m,h");
			}
			mute(sender, player, "5m", true);
			return;
		}
		
		if (getTimeStamp(time) == -1)
			msg(sender, "Invalid time format, Ex. 20m");
		if (getTimeStamp(time) == -2)
			msg(sender, "Unknown time value, accepts s,m,h");
		if (getTimeStamp(time) == -3)
			msg(sender, "Time too long! Max allowed time is 5 hours (5h)");
		if (getTimeStamp(time) < 0)
			return;

		sql.setMuteTime(realPlayer.getName(), (int) getTimeStamp(time));
		int left = (int)(sql.getMuteTime(realPlayer.getName()) - System.currentTimeMillis() / 1000);
		msg(realPlayer, "You were muted for " + timeLeft(left));
		if (!def)
			for (Player on : Bukkit.getOnlinePlayers()) {
				if (on.hasPermission("ddchat.prefix")) {
					msg(on, player + " muted for " + timeLeft(left));
				}
			}
		if (!(sender instanceof Player))
			msg(sender, realPlayer.getName() + " successfully muted.");
	}

//	@EventHandler
//	public void onPlayerChat(AsyncPlayerChatEvent event){
//		Player player = event.getPlayer();
//		log("HA");
//		if (playerMuted(player.getName())) {
//			log("A");
//			if (checkTime(event.getPlayer().getName())) {
//				int left = (int)(plugin.chat.sql.getMuteTime("muted-players." + player.getName()) - System.currentTimeMillis() / 1000);
//				msg(event.getPlayer(), "You are muted, and will stay muted for the remaining:");
//				msg(event.getPlayer(), timeLeft(left));
//				try {
//					event.setCancelled(true);
//				} catch (Exception e) {
//					event.setMessage("");
//				}
//			}
//		}
//	}

//	@EventHandler(priority=EventPriority.HIGHEST)
	public void onCommandPreProcess(PlayerCommandPreprocessEvent event)
	{
		Player player = event.getPlayer();
		if (playerMuted(player.getName())){
			for (int i = 0; i < blockedCommands.size(); i++) {
				if (event.getMessage().startsWith(blockedCommands.get(i)))
				{
					if (checkTime(event.getPlayer().getName())) {
						int left = (int)(sql.getMuteTime(player.getName()) - System.currentTimeMillis() / 1000);
						msg(event.getPlayer(), "You are muted, and will stay muted for the remaining:");
						msg(event.getPlayer(), timeLeft(left));
						event.setCancelled(true);
					}
				}
			}
		}
	}

	public void msg(CommandSender sender, String msg){
		if (sender instanceof Player) {
			Player player = (Player) sender;
			player.sendMessage("[" + ChatColor.RED + "Mute" + ChatColor.WHITE + "] " + ChatColor.AQUA + msg);
		} else {
			log(msg);
		}
	}
	
	public boolean playerMuted(String player) {
		return sql.getMuteTime(player) != 0;
	}
	
	public int getTimeStamp(String time) {
		int timestamp = (int) (System.currentTimeMillis() / 1000);
		String unit = time.substring(time.length() - 1, time.length());
		String input = time.substring(0, time.length() - 1);
		int add = 0;
		try {
			add = Integer.parseInt(input);
		} catch (Exception e) {
			return -1;
		}
		if (unit.equalsIgnoreCase("s")) {
			timestamp += add;
		} else if (unit.equalsIgnoreCase("m")) {
			timestamp += add*60;
		} else if (unit.equalsIgnoreCase("h")) {
			timestamp += add*60*60;
		} else {
			return -2;
		}
		if (timestamp - System.currentTimeMillis() / 1000 > 60*60*5)
			return -3;
		return timestamp;
	}
	
	public boolean checkTime(String player) {
		int time = sql.getMuteTime(player);
		if (System.currentTimeMillis() / 1000 > time) {
			mute(null, player, null, false);
			return false;
		}
		return true;
	}
	
	public String timeLeft(int time) {
		String msg = "";
		int divid = 0;
		if (time >= 60*60) {
			divid = time / (60*60);
			msg += divid + " hour";
			if (divid > 1)
				msg+= "s";
			time -= divid * (60*60);
			if (time != 0)
				msg += ", ";
			log(divid + ", " + time);
		}
		if (time >= 60) {
			divid = time / 60;
			msg += divid + " minute";
			if (divid > 1)
				msg+= "s";
			time -= divid * 60;
			if (time != 0)
				msg += ", ";
			if (time != 0)
				msg += "and ";
		}
		if (time != 0) {
			divid = time;
			msg += divid + " second";
			if (divid > 1)
				msg+= "s";
		}
		return msg;
	}
	
	public void log(String info) {
		plugin.getLogger().info("<FullMute> " + info);
	}
} public class HeartBeat {
	
	private CustomPlugin plugin;
	
	public HeartBeat(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public double tps = 20;
	boolean ping = true;

	public void enable() {
//		plugin.getServer().getPluginManager().registerEvents(this, plugin);

		plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() {
					@Override
					public void run() {
						long timestamp = System.currentTimeMillis() / 1000;
						ping = ping();
						try {
							writeFile("heartbeat.txt", timestamp + "\nDISABLED\n" + plugin.getServer().getOnlinePlayers().length + "\n" + ping);
						} catch (IOException e) {
							log("HeartBeat was not able to update time stamp!");
							log("Might receieve email notifications that server is down!");
						}
					}
				}, 500, 1200);
//		plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() {
//
//					long sec;
//					long second = 0;
//					int ticks;
//
//					@Override
//					public void run() {
//						sec = (System.currentTimeMillis() / 1000);
//
//						if (second == sec) {
//							ticks++;
//						} else {
//							second = sec;
//							tps = ((tps + ticks) / 2);
//							ticks = 0;
//						}
//					}
//				}, 100, 1);

		log("Enabled");

	}
	
	public void disable() {
		long timestamp = (System.currentTimeMillis() / 1000) + 60;
		try {
			writeFile("heartbeat.txt", timestamp + "\n" + tps + "\n" + plugin.getServer().getOnlinePlayers().length + "\n" + ping);
		} catch (IOException e) {
			log("HeartBeat was not able to update time stamp!");
			log("Might receieve email notifications that server is down!");
		}
	}
	
//	@EventHandler(priority = EventPriority.HIGHEST)
//    public void onServerListPing(ServerListPingEvent event){
//        if(!ping)
//        	event.setMotd(ChatColor.AQUA + "DD" + ChatColor.RED + " IS DOWN, working on a fix.");
//    }

	public static void writeFile(String filename, String text) throws IOException {
	    FileOutputStream fos = null;
	    try {
	      fos = new FileOutputStream(filename);
	      fos.write(text.getBytes("UTF-8"));
	    } catch (IOException e) {
	      close(fos);
	      throw e;
	    }
	  }

	public static void close(Closeable closeable) {
		try {
			closeable.close();
		} catch (IOException ignored) {
		}
	}
	
	public static boolean ping()
	{
		try {
			//make a URL to a known source
			URL url = new URL("http://www.google.com");

			//open a connection to that source
			HttpURLConnection urlConnect = (HttpURLConnection)url.openConnection();

			//trying to retrieve data from the source. If there
			//is no connection, this line will fail
			urlConnect.getContent();

		} catch (UnknownHostException e) {
			System.out.println("[HeartBeat] Connection Failure");
			return false;
		}
		catch (IOException e) {
			System.out.println("[HeartBeat] Connection Failure");
			return false;
		}
		return true;
	}
	
	public void log(String info) {
		plugin.getLogger().info("<HeartBeat> " + info);
	}
} public class Homes {
	private CustomPlugin plugin;

	public Homes(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	public boolean onCommand(CommandSender sender, String label, String[] args) {
		if (!(sender instanceof Player)) {
			log("idgaf");
			return true;
		}
		
		Player player = (Player) sender;
		if (player.getWorld().getName().equals("EventWorld")) {
			msg(player, "You can't use homes in the EventWorld");
			return true;
		}

		String homeName;
		if (args.length == 0)
			homeName = "home";
		else
			homeName = args[0];
		int amountOfHomes = getHomesAmount(player);
		
		//sethome, delhome, home, homes
		if (label.equalsIgnoreCase("sethome")) {
			if (amountOfHomes > getHomesList(player).size() || amountOfHomes == -1) {
				addHome(player, homeName, player.getLocation());
			} else {
				msg(player, "You have exceeded your maximum of " + amountOfHomes + " homes.");
			}
			return true;
		} else if (label.equalsIgnoreCase("delhome")) {
			if (getHomesList(player).contains(homeName)) {
				delHome(player, homeName);
			} else {
				msg(player, "Your home '" + homeName + "' does not exist!");
			}
			return true;
		} else if (label.equalsIgnoreCase("home")) {
			teleportPlayer(player, getHomeLocation(player, homeName));
			return true;
		} else if (label.equalsIgnoreCase("homes")) {
			msg(player, "Your current homes list:");
			for (String home : getHomesList(player)) {
				player.sendMessage(" - " + ChatColor.AQUA + home);
			}
			return true;
		}
		return false;
	}
	
	Map<String, String> toTp = new HashMap<String, String>();
	
	public void onBungeeMessageReceived(String channel, Player player, byte[] message) {
		DataInputStream in = new DataInputStream(new ByteArrayInputStream(message));
        String subchannel = null;
		try {
			subchannel = in.readUTF();
		} catch (IOException e) {
			log("Could not read plugin message");
			e.printStackTrace();
		}
        if (subchannel.equals("DDCustomPlugin_Homes")) {
        	try {
        		short len = in.readShort();
        		byte[] msgbytes = new byte[len];
        		in.readFully(msgbytes);
        		
        		DataInputStream msgin = new DataInputStream(new ByteArrayInputStream(msgbytes));
				String playerName = msgin.readUTF(); 
				String location = msgin.readUTF();
				
//				log(location + "; " + playerName);
				
				ArrayList<String> onlinePlayers = new ArrayList<String>();
				
				for (Player onlineplayer : Bukkit.getOnlinePlayers()) {
					onlinePlayers.add(onlineplayer.getName());
				}
				
				if (onlinePlayers.contains(playerName)) {
					teleportPlayer(Bukkit.getPlayer(playerName), location);
				} else {
					toTp.put(playerName, location);
				}
        	} catch (Exception e) {}
        }
	}
	
	public void onJoinEvent(PlayerJoinEvent event) {
		String name = event.getPlayer().getName();
		if (toTp.containsKey(name)) {
			teleportPlayer(event.getPlayer(), toTp.get(name));
			toTp.remove(name);
		}
	}
	
	private ArrayList<String> getHomesList(Player player) {
		ArrayList<String> homes = new ArrayList<String>();
		
		ResultSet result = null;
		Connection con = null;
		try {
			con = SQL.getConnection();

			Statement st = (Statement) con.createStatement(); 
			result = st.executeQuery("SELECT `home_name` FROM BungeeHomes WHERE `player`='" + player.getName() + "';");
			while (result.next()) {
				homes.add(result.getString("home_name"));
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return homes;
	}
	
	private void teleportPlayer(Player player, String location) {
//		log("TP: " + player.getName() + ": " + location);
		String[] array = location.split(";");
		if (array.length == 0) {
			msg(player, "The location for this home is blank.");
			return;
		}
		if (getServerWorld(array[0]).equals(plugin.detectedServer())) {
			Location loc = new Location(Bukkit.getWorld(array[0]), Double.parseDouble(array[1]), Double.parseDouble(array[2]), Double.parseDouble(array[3]), Float.parseFloat(array[5]), Float.parseFloat(array[4]));
			if (loc.getWorld() == null) {
				msg(player, "The location for this home has a world that is unavailable");
				return;
			}
			player.teleport(loc);
//			msg(player, "You have been teleported to your home");
		} else {
			String server = getServerWorld(array[0]);
			if (server.equals("")) {
				msg(player, "The location for this home refers to a server that doesn't exist.");
				return;
			}
			
			ByteArrayOutputStream b = new ByteArrayOutputStream();
			DataOutputStream out = new DataOutputStream(b);
			
			try {
				
				out.writeUTF("Forward");
				out.writeUTF("ALL");
				out.writeUTF("DDCustomPlugin_Homes");

				ByteArrayOutputStream msgbytes = new ByteArrayOutputStream();
				DataOutputStream msgout = new DataOutputStream(msgbytes);
				msgout.writeUTF(player.getName());
				msgout.writeUTF(location);

				out.writeShort(msgbytes.toByteArray().length);
				out.write(msgbytes.toByteArray());

				player.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
				
				b = new ByteArrayOutputStream();
				out = new DataOutputStream(b);

				out.writeUTF("Connect");
				out.writeUTF(server);
			
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			player.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
		}
	}
	
	private String getServerWorld(String world) {
		if (world.equals("Survival") || world.equals("TownWorld") || world.equals("End") || world.equals("Nether"))
			return "survival";
		if (world.equals("EventWorld"))
			return "events";
		if (world.equals("Build"))
			return "creative";
		if (world.equals("Destruction"))
			return "destruction";
		if (world.equals("SkyBlock"))
			return "skyblock";
		return "";
	}
	
	private String getHomeLocation(Player player, String homeName) {
		//Location string is WORLD;X;Y;Z;YAW;PITCH
		String location = "";
		ResultSet result = null;
		Connection con = null;
		try {
			con = SQL.getConnection();

			Statement st = (Statement) con.createStatement(); 
			result = st.executeQuery("SELECT * FROM `BungeeHomes` WHERE `player`='" + player.getName() + "' && `home_name`='" + homeName + "';");
			
			while (result.next()) {
				location += result.getString("world") + ";";
				location += result.getString("x") + ";";
				location += result.getString("y") + ";";
				location += result.getString("z") + ";";
				location += result.getString("yaw") + ";";
				location += result.getString("pitch");
			}

			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return location;
	}
	
	private void addHome(Player player, String homeName, Location homeLoc) {
		SQL.singleQuery("DELETE FROM `BungeeHomes` WHERE `player`='" + player.getName() + "' && `home_name`='" + homeName + "';");

		SQL.singleQuery("INSERT INTO `BungeeHomes` (`player`, `home_name`, `server`, `world`, `x`, `y`, `z`, `yaw`, `pitch`) VALUES " + 
				"('" + player.getName() + "', '" + homeName + "', '" + plugin.detectedServer() + "', '" + homeLoc.getWorld().getName() + "', " + homeLoc.getX() + ", " + homeLoc.getY() + ", " + homeLoc.getZ() + ", " + homeLoc.getYaw() + ", " + homeLoc.getPitch() + ");");

		msg(player, "Home set");
	}
	
	private void delHome(Player player, String homeName) {
		SQL.singleQuery("DELETE FROM `BungeeHomes` WHERE `player`='" + player.getName() + "' && `home_name`='" + homeName + "';");
		msg(player, "Home deleted");
	}
	
	private int getHomesAmount(Player player) {
		@SuppressWarnings("static-access")
		String rank = plugin.chat.perms.getPlayerGroups(player)[0];
		if (rank.contains("Player"))
			return 5;
		if (rank.contains("YouTuber"))
			return 5;
		if (rank.contains("Respected"))
			return 5;
		if (rank.contains("Assistant"))
			return 5;
		if (rank.contains("VIP"))
			return 10;
		if (rank.contains("Premium"))
			return 15;
		if (rank.contains("Elite"))
			return 25;
		if (rank.contains("Exclusive"))
			return 30;
		if (rank.contains("Ultimate"))
			return 50;
		if (rank.contains("DemiGod"))
			return -1;
		if (rank.contains("Mod"))
			return 10;
		if (rank.contains("VIMod"))
			return 20;
		if (rank.contains("PMod"))
			return 25;
		if (rank.contains("EMod"))
			return 35;
		if (rank.contains("ExMod"))
			return 40;
		if (rank.contains("UMod"))
			return 60;
		if (rank.contains("DGMod"))
			return -1;
		if (rank.contains("HeadMod"))
			return 100;
		if (rank.contains("Admin"))
			return -1;
		if (rank.contains("HeadAdmin"))
			return -1;
		if (rank.contains("Owner"))
			return -1;
		return 5;
	}
	
	private void msg(Player player, String msg) {
		player.sendMessage(ChatColor.DARK_BLUE + "[" + ChatColor.WHITE + "DDHomes" + ChatColor.DARK_BLUE + "] " + ChatColor.GREEN + msg);
	}

	public void log(String info) {
		plugin.getLogger().info("<Homes> " + info);
	}
} public class HubPortals {
	private CustomPlugin plugin;

	public HubPortals(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	private ArrayList<Player> queue = new ArrayList<Player>();
	
	public void onPlayerMoveEvent(PlayerMoveEvent event) {
		Player player = event.getPlayer();
		if (!queue.contains(player)) {
			Location playerLoc = player.getLocation();
			if (playerLoc.getY() < 11) {
				if (inCreativeArea(playerLoc)) {
					send(player, "creative");
				}
				if (inEventsArea(playerLoc)) {
					send(player, "events");
				}
				if (inDestructionArea(playerLoc)) {
					send(player, "destruction");
				}
				if (inSkyBlockArea(playerLoc)) {
					send(player, "skyblock");
				}
				if (inEWPortal(playerLoc)) {
					send(player, "survival");
				}
				if (inSBPortal(playerLoc)) {
					send(player, "survival");
				}
				if (inCRPortal(playerLoc)) {
					send(player, "survival");
				}
			}
		}
	}
	
	private void send(Player player, String server) {
		ByteArrayOutputStream b = new ByteArrayOutputStream();
		DataOutputStream out = new DataOutputStream(b);

		try {
			out.writeUTF("Connect");
			out.writeUTF(server);
		} catch (IOException e) {
			e.printStackTrace();
		} 
		player.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
		queue.add(player);
	}
	
	public boolean inCreativeArea(Location l) {
		

		if (l.getWorld().getName().equals("Survival"))
			if (l.distance(new Location(l.getWorld(), 76.5, 0, 186.5)) < 10)
				return true;
		return false;
	}

	public boolean inEventsArea(Location l) {
		

		if (l.getWorld().getName().equals("Survival"))
			if (l.distance(new Location(l.getWorld(), 76.5, 0, 210.5)) < 10)
				return true;
		return false;
	}

	public boolean inDestructionArea(Location l) {
		

		if (l.getWorld().getName().equals("Survival"))
			if (l.distance(new Location(l.getWorld(), 52.5, 0, 186.5)) < 10)
				return true;
		return false;
	}

	public boolean inSkyBlockArea(Location l) {
		

		if (l.getWorld().getName().equals("Survival"))
			if (l.distance(new Location(l.getWorld(), 52.5, 0, 210.5)) < 10)
				return true;
		return false;
	}

	public boolean inEWPortal(Location l) {
		

		if (l.getWorld().getName().equals("EventWorld"))
			if (l.distance(new Location(l.getWorld(), -455.5, 0, -508.5)) < 10)
				return true;
		return false;
	}
	
	public boolean inSBPortal(Location l) {
		

		if (l.getWorld().getName().equals("SkyBlock"))
			if (l.distance(new Location(l.getWorld(), 38.5, 0, 110.5)) < 10)
				return true;
		return false;
	}

	public boolean inCRPortal(Location l) {
		

		if (l.getWorld().getName().equals("Build"))
			if (l.distance(new Location(l.getWorld(), 14.5, 0, 0.5)) < 10)
				return true;
		return false;
	}
	
	public boolean inAPortal(Player player) {
		Location l = player.getLocation();
		if (l.getY() < 11) {
			if (inCreativeArea(l))
				return true;
			if (inEventsArea(l))
				return true;
			if (inDestructionArea(l))
				return true;
			if (inSkyBlockArea(l))
				return true;
			if (inEWPortal(l))
				return true;
			if (inSBPortal(l))
				return true;
			if (inCRPortal(l))
				return true;
		}
		return false;
	}
	
	public void onPlayerFallEvent(EntityDamageEvent event) {
		if (event.getCause() == DamageCause.FALL && event.getEntity() instanceof Player) {
			Player player = (Player) event.getEntity();
			if (inAPortal(player)) {
				event.setCancelled(true);
			}
		}
	}
	
	public void onJoinEvent(PlayerJoinEvent event) {
		Player player = event.getPlayer();
		if (inAPortal(player)) {
			player.setFallDistance(0);
			player.teleport(player.getLocation().clone().add(0,20,0));
			plugin.getServer().dispatchCommand(player, "worldspawn");
		}
		if (queue.contains(player)) {
			queue.remove(player);
		}
	}

	public void log(String info) {
		plugin.getLogger().info("<HubPortals> " + info);
	}
} public class LaunchPad {

	private CustomPlugin plugin;
	
	private Map<Player, Integer> launched = new HashMap<Player, Integer>();
	
	public LaunchPad(CustomPlugin plugin) {
		this.plugin = plugin;
	}
	
	public void enable() {
//		plugin.getServer().getPluginManager().registerEvents(this, plugin);
		log("Enabled");
	}
	
	public void log(String info) {
		plugin.getLogger().info("<LaunchPad> " + info);
	}

	public void sendFlying(Block block, Player player) {
		Block u = block.getLocation().clone().add(0,-1,0).getBlock();
		if (u.getType() != Material.OBSIDIAN) {
			return;
		}
		boolean n = block.getLocation().clone().add(0,-1,1).getBlock().getType() == Material.REDSTONE_LAMP_OFF;
		boolean s = block.getLocation().clone().add(0,-1,-1).getBlock().getType() == Material.REDSTONE_LAMP_OFF;
		boolean e = block.getLocation().clone().add(1,-1,0).getBlock().getType() == Material.REDSTONE_LAMP_OFF;
		boolean w = block.getLocation().clone().add(-1,-1,0).getBlock().getType() == Material.REDSTONE_LAMP_OFF;
//		player.setVelocity(new Vector(0, 1, 0));
		int total = 0;
		
		if (n)
			total++;
		if (s)
			total++;
		if (e)
			total++;
		if (w)
			total++;
		if (total > 1) {
			return;
		} else if (total == 1) {
			block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, 80);	
		}
		
		if (n)
			player.setVelocity(new Vector(0,1,10));
		if (s)
			player.setVelocity(new Vector(0,1,-10));
		if (e)
			player.setVelocity(new Vector(10,1,0));
		if (w)
			player.setVelocity(new Vector(-10,1,0));
		
	}
	
//	@EventHandler
	public void onPlayerInteractEvent(PlayerInteractEvent event) {
		if (event.getClickedBlock() != null) {
			if (event.getAction() == Action.PHYSICAL && event.getClickedBlock().getType() == Material.STONE_PLATE) {
//				Block b = event.getClickedBlock();
//				int x = b.getLocation().getBlockX();
//				int y = b.getLocation().getBlockY();
//				int z = b.getLocation().getBlockZ();
//				247, 192, 258
//				271, 192, 258
//				if (b.getWorld().getName().equals("Survival") && y == 192 && z == 258) {
//					if (x == 271) {
//						event.getPlayer().setVelocity(new Vector(-10, 1, 0));
//						return;
//					}
//					if (x == 247) {
//						event.getPlayer().setVelocity(new Vector(10, 1, 0));
//						return;
//					}
//				}
				//START SHOP SCRIPT
				if (event.getClickedBlock().getLocation().equals(new Location(Bukkit.getWorld("Survival"), 213, 68, 252))) {
					event.getPlayer().setVelocity(new Vector(-5.5, 2, -3.6));
					launched.put(event.getPlayer(), (int) (System.currentTimeMillis()/1000));
				}
				//END SHOP SCRIPT
				sendFlying(event.getClickedBlock(), event.getPlayer());
			}
		}
	}
	
//	@EventHandler
	@SuppressWarnings("deprecation")
	public void onPlayerDamage(EntityDamageEvent event){
		if (event.getEntity() instanceof Player){
			if (event.getCause() == DamageCause.FALL){
				Location l = event.getEntity().getLocation().add(0, -2, 0);
				Block block = l.getBlock();
				//START SHOP SCRIPT
				if (block.getType() == Material.SPONGE)
					if (block.getData() == (byte) 5)
						event.setCancelled(true);
				Player player = (Player) event.getEntity();
				if (launched.containsKey(player)) {
					if (System.currentTimeMillis()/1000 < launched.get(event.getEntity()) + 3) {
						event.setCancelled(true);
						if (!(block.getType() == Material.SPONGE && block.getData() == (byte) 5))
							player.teleport(new Location(Bukkit.getWorld("Survival"), 184.5, 80, 227.5, player.getLocation().getYaw(), player.getLocation().getPitch()));
						else
							launched.remove(player);
					} else {
						launched.remove(player);
					}
						
				}
				//END SHOP SCRIPT
				l = event.getEntity().getLocation().add(0, -1, 0);
				block = l.getBlock();
				if (block.getType() != Material.OBSIDIAN) {
					return;
				}
				boolean n = block.getLocation().clone().add(0,-1,1).getBlock().getType() == Material.REDSTONE_LAMP_OFF;
				boolean s = block.getLocation().clone().add(0,-1,-1).getBlock().getType() == Material.REDSTONE_LAMP_OFF;
				boolean e = block.getLocation().clone().add(1,-1,0).getBlock().getType() == Material.REDSTONE_LAMP_OFF;
				boolean w = block.getLocation().clone().add(-1,-1,0).getBlock().getType() == Material.REDSTONE_LAMP_OFF;
//				player.setVelocity(new Vector(0, 1, 0));
				int total = 0;
				
				if (n)
					total++;
				if (s)
					total++;
				if (e)
					total++;
				if (w)
					total++;
				if (total > 1) {
					return;
				}
				event.setCancelled(true);
			}
		}
	}
	
} public class Nameless {

	private CustomPlugin plugin;

	public Nameless(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	public boolean onCommand(CommandSender sender, String args[]) {
		if (sender instanceof Player) {
			Player player = (Player) sender;
			if (!player.hasPermission("customplugin.nameless")) {
				player.sendMessage(ChatColor.RED + "You can't use this command.");
				return true;
			}
			String msg = "";
			for (String arg : args) {
				msg += arg + " ";
			}
			Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', msg));
		}
		return true;
	}

	public void log(String info) {
		plugin.getLogger().info("<Nameless> " + info);
	}
} public class RespectedAutoPromote {
	private CustomPlugin plugin;

	public RespectedAutoPromote(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	public boolean onCommand(CommandSender sender) {
		if (!(sender instanceof Player)) {
			log("INFINITY");
			return true;
		}
		Connection con = null;
		try {
			con = SQL.getConnection();

			Statement st = (Statement) con.createStatement(); 
			ResultSet result = st.executeQuery("SELECT `onlinetime` FROM `lb-players` WHERE `playername` = '" + sender.getName() + "';");

			while (result.next()) {
				int onlinetime = result.getInt("onlinetime");
				int minutes = onlinetime/60;
				int seconds = onlinetime - (minutes*60);
				int hours = minutes / 60;
				minutes = minutes - (hours*60);
				sender.sendMessage(ChatColor.GREEN + "You have been online a total of " + ChatColor.AQUA + hours + " hours, " + minutes + " minutes, " + seconds + " seconds");
			}
		} catch (SQLException e1) {
			e1.printStackTrace();
		}
		return true;
	}
	
	public void onPlayerJoinEvent(PlayerJoinEvent event) {
		@SuppressWarnings("static-access")
		String group = plugin.chat.perms.getPlayerGroups(event.getPlayer())[0];
		if (group.contains("Player")) {
			Connection con = null;
			try {
				con = SQL.getConnection();

				Statement st = (Statement) con.createStatement(); 
				ResultSet result = st.executeQuery("SELECT `onlinetime` FROM `lb-players` WHERE `playername` = '" + event.getPlayer().getName() + "';");

				while (result.next()) {
					int onlinetime = result.getInt("onlinetime");
					if (onlinetime > 86400) {
						Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "pex user " + event.getPlayer().getName() + " group set Respected");
						Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "gcmd pex reload");
						event.getPlayer().sendMessage(ChatColor.GREEN + "CONGRATS! You're now a Diamond Dominion RESPECTED player");
					}
				}
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
		}
	}

	public void log(String info) {
		plugin.getLogger().info("<RespectedAutoPromote> " + info);
	}
} public class ServerRestart {
	private CustomPlugin plugin;

	public ServerRestart(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	public boolean onRestartCommand(CommandSender sender) {
		if (sender instanceof Player)
			return false;
		cmd("save-all");
		if (plugin.detectedServer().equals("survival")) {
			for (Player player : Bukkit.getOnlinePlayers()) {
				plugin.commandModifier.tpServer(player, "events");
			}
		} else {
			for (Player player : Bukkit.getOnlinePlayers()) {
				plugin.commandModifier.tpServer(player, "survival");
			}
		}
		Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable(){
			@Override
			public void run() {
				cmd("stop");
			}
		}, 2);
		return true;
	}
	
	public boolean onWarnCommand(CommandSender sender) {
		if (sender instanceof Player)
			return false;
		Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', "&1&l==&4&oWARNING&1&l== &cServer restarting in 1 minute! &1&l==&4&oWARNING&1&l=="));
		return true;
	}
	
	private void cmd(String cmd) {
		Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd);
	}

	public void log(String info) {
		plugin.getLogger().info("<ServerRestart> " + info);
	}
} public class SignEdit {
	private CustomPlugin plugin;

	public SignEdit(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	@SuppressWarnings("deprecation")
	public boolean onCommand(CommandSender sender, String args[]) {
		Player p = (Player) sender;
		if (!p.hasPermission("customplugin.signedit")) {
			p.sendMessage(ChatColor.RED + "You can't edit signs... Sorry!");
			return true;
		}
		Block b = p.getTargetBlock(null, 5);
		if (b != null && (b.getType().equals(Material.WALL_SIGN) || b.getType().equals(Material.SIGN_POST))) {
			if (args.length >= 1) {
				try {
					int lineNum = Integer.parseInt(args[0]);
					Sign s = (Sign) b.getState();
					if (args.length == 1) {
						s.setLine(lineNum - 1, "");
						s.update();
						return true;
					}
					String a = "";
					for (int i = 1; i < args.length; i++) {
						a += args[i] + " ";
					}
					a = a.substring(0, a.length()-1);
					if (a.length() > 16) {
						p.sendMessage(ChatColor.RED + "A sign line can be up to 16 characters long");
					}
					s.setLine(lineNum - 1, ChatColor.translateAlternateColorCodes('&', a));
					s.update();
				} catch (Exception e) {
					p.sendMessage(ChatColor.RED + "Type /edit <lineNum> <line>");
				}
				return true;
			} else {
				p.sendMessage(ChatColor.RED + "Type /edit <lineNum> <line>");
				return true;
			}
		} else {
			p.sendMessage(ChatColor.RED + "You must look at a sign to edit");
			return true;
		}
	}

	public void log(String info) {
		plugin.getLogger().info("<SignEdit> " + info);
	}
} @SuppressWarnings("deprecation")
public class SpawnerSwitch {
	
	private CustomPlugin plugin;
	private ArrayList<CreatureType> mobs = new ArrayList<CreatureType>();
	LivingEntity e;
	
	public SpawnerSwitch(CustomPlugin plugin) {
		this.plugin = plugin;
	}
	
	public void enable() {
//		plugin.getServer().getPluginManager().registerEvents(this, plugin);
		mobs.add(CreatureType.PIG);
		mobs.add(CreatureType.SHEEP);
		mobs.add(CreatureType.COW);
		mobs.add(CreatureType.CHICKEN);
		mobs.add(CreatureType.ZOMBIE);
		mobs.add(CreatureType.SKELETON);
		mobs.add(CreatureType.SPIDER);
		mobs.add(CreatureType.CAVE_SPIDER);
		mobs.add(CreatureType.PIG_ZOMBIE);
		log("Enabled");
	}
	
	private int getInt(CreatureType c) {
		for (int i = 0; i < mobs.size(); i++) {
			if (mobs.get(i) == c)
				return i;
		}
		return 0;
	}
	
	private void playSound(CreatureType c, Block b) {
		e = b.getWorld().spawnCreature(b.getLocation().add(.5, 1, .5), c);
		e.damage(200);
	}
	
	private boolean isAllowedToBeBreaked(Block spawner) {
		Block lowerBlock = spawner.getRelative(BlockFace.DOWN);
		if (lowerBlock.getType() == Material.GLOWSTONE && lowerBlock.getData() == (byte)1)
			return false;
		return true;
	}
	
	public void msg(Player player, String msg) {
		player.sendMessage(ChatColor.DARK_GREEN + "[" + ChatColor.RED + "Spawner" + ChatColor.DARK_GREEN + "] " + ChatColor.GREEN + msg);
	}
	
//	@EventHandler
	public void onEntityDeath(EntityDeathEvent event) {
		if (event.getEntity() == e) {
			event.getDrops().clear();
			event.setDroppedExp(0);
		}
		
	}
	
//	@EventHandler
	public void onPlayerPunch(PlayerInteractEvent event) {
		final Block spawner = event.getClickedBlock();
		if (spawner != null && spawner.getType() == Material.MOB_SPAWNER) {
			Player player = event.getPlayer();
			String world = player.getWorld().getName();
			if (!world.equals("GameWorld") && isAllowedToBeBreaked(spawner)) {
				CreatureSpawner cage = ((CreatureSpawner) spawner.getState());
				if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
					if (!player.getInventory().getItemInHand().getType().isBlock() || player.getItemInHand().getType() == Material.AIR) {
						int i = getInt(cage.getCreatureType()) + 1;
						try {
							cage.setCreatureType(mobs.get(i));
							playSound(mobs.get(i), spawner);
						} catch (Exception e) {
							cage.setCreatureType(mobs.get(0));
							playSound(mobs.get(0), spawner);
						}
						//					Location loc = spawner.getLocation();
						//					if (i == 1) {
						//						spawner.getWorld().playSound(loc, Sound.SHEEP_IDLE , 3F, 3F);
						//					} else if (i == 2) {
						//						spawner.getWorld().playSound(loc, Sound.COW_IDLE, 3F, 3F);
						//					}
						msg(player, "Changed to a " + ChatColor.AQUA + cage.getCreatureTypeName() + ". " + ChatColor.GREEN + "Relog to see it.");
					} else {
						msg(player, "You can only change spawners when you have nothing in your hand.");
					}
				} else if (event.getAction() == Action.LEFT_CLICK_BLOCK) {
					player.sendMessage(ChatColor.RED + "=========== " + ChatColor.DARK_RED + "Mob Spawner List" + ChatColor.RED + " ===========");
					for (CreatureType c : mobs) {
						String msg = ChatColor.DARK_GREEN + String.valueOf(getInt(c) + 1) + ". " + ChatColor.GREEN + c.getName();
						if (c.getName().equals("Cow"))
							msg += ChatColor.RED + "                 Current Spawner Type:";
						if (c.getName().equals("Chicken"))
							msg += " " + ChatColor.BOLD + "         " + cage.getCreatureTypeName();
						if (c.getName().equals("CaveSpider"))
							msg += ChatColor.RED + "  Use like you would a noteblock";
						player.sendMessage(msg);
					}
				}
			} else {
				msg(player, "You can not change this spawner.");
			}
		}
	}

	public void log(String info) {
		plugin.getLogger().info("<SpawnerSwitch> " + info);
	}
} public class Trampoline {
	private CustomPlugin plugin;

	public Trampoline(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	@SuppressWarnings("deprecation")
	public void onPlayerInteract(PlayerInteractEvent event) { 
		Player player = event.getPlayer();
		if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
			if (event.getClickedBlock().getTypeId() == 19) {
				player.setVelocity(new Vector(player.getVelocity().getX(), 1.3D, player.getVelocity().getZ()));
				player.getWorld().playEffect(event.getClickedBlock().getLocation(), Effect.STEP_SOUND, 19);
			}	
		}
	}

	@SuppressWarnings("deprecation")
	public void onEntityDamage(EntityDamageEvent event) {
		if (event.getEntity() instanceof Player) {
			if (event.getCause() == DamageCause.FALL) {
				Location l = event.getEntity().getLocation().add(0, -1, 0);
				Material mBelow = l.getBlock().getType();
				if (mBelow == Material.SPONGE) {
					event.setCancelled(true);
					Player player = (Player) event.getEntity();
					if (!player.isSneaking()) {
						player.setVelocity(new Vector(player.getVelocity().getX(), 1.3D, player.getVelocity().getZ()));
						if (player.hasPermission("customplugin.crazytramp") || l.getBlock().getData() == (byte) 1)
							player.setVelocity(new Vector(player.getVelocity().getX(), 10D, player.getVelocity().getZ()));
						player.getWorld().playEffect(l, Effect.STEP_SOUND, 19);
					}
				}
			}
		}
	}
	
	public void log(String info) {
		plugin.getLogger().info("<Trampoline> " + info);
	}
} public class Voodoo {
	private CustomPlugin plugin;

	public Voodoo(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	@SuppressWarnings("deprecation")
	public void onPlayerInteract(final PlayerInteractEvent event) { 
		final Player player = event.getPlayer();
		if (player.hasPermission("customplugin.voodoo")) {
			ItemStack i = player.getItemInHand();
			if (i.getTypeId() == 397 && i.getDurability() == (byte) 3) {
				SkullMeta skull = (SkullMeta)i.getItemMeta();
				Player p = Bukkit.getPlayer(skull.getOwner());
				if (p != null) {
					if (event.getAction().equals(Action.RIGHT_CLICK_AIR) || event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
						p.setVelocity(player.getLocation().getDirection().multiply(-1));
					} else {
						p.setVelocity(player.getLocation().getDirection());
					}
				}
			}
		}
	}
	
	public void log(String info) {
		plugin.getLogger().info("<Voodoo> " + info);
	}
} public class VoteRewards {

	CustomPlugin plugin;
	
	public VoteRewards(CustomPlugin plugin) {
		this.plugin = plugin;
	}
	public Map<String, Map<Integer, Integer>> rewardCache = new HashMap<String, Map<Integer, Integer>>();
	String head = "&2|&6-----------=-=-----=-=&2[ &bD D &2]&6=-=-----=-=---------&2|";

	@SuppressWarnings("deprecation")
	public void enable() {
		Bukkit.getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
			@Override
			public void run() {
				updateRewards();
			}
		}, 5, 20*5);
		
		log("Enabled");
	}

	public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
		if (args.length == 0 || !(sender instanceof Player)) {
			msg(sender, head);
			msg(sender, "  &lGO TO &b&ohttp://www.diamonddominion.net/vote");
			msg(sender, "  &a&lVOTE FOR US! -=- YOU WILL GET PRIZES");
			msg(sender, "&2|&b/vote redeem&6 to exchange votes prizes.");
			msg(sender, "&2|&b/vote stats&6 to see what you currently have.");
			msg(sender, head);
//			msg(sender, "Visit the website to use up donation credits you earn.");
//			msg(sender, "Voting helps our server gain popularity on server listing sites.");
			return true;
		} else {
			Player player = (Player) sender;
			String arg = args[0];
			if (arg.equalsIgnoreCase("redeem")) {
				if (args.length < 3) {
					msg(player, head);
					msg(player, "You have &b" + VoteSQL.getVotesNotRewarded(player.getName()) + "&6 votes to buy prizes.");
					msg(player, "Type &b/vote redeem <prize id> <prize amount>");
					msg(player, "| &2PrizeID&6 | &2VoteCost&6 | -- &2Prize Name &6--");
					for (int x = 1; x <= VotePrize.prizeAmount; x++) {
						msg(player, "&6 -- &b" + x + " &6-- | -- &b" + VotePrize.getCost(x) + "&6 --- | &a" + VotePrize.getDescription(x));
					}
					msg(player, head);
					return true;
				} else {
					String strid = args[1];
					int id;
					try {
						id = Integer.parseInt(strid);
					} catch (Exception e) {
						msg(player, "&4Error: &cPrize ID is incorrect.");
						msg(player, "Type &b/vote redeem <prize id> <prize amount>");
						return true;
					}
					if (!VotePrize.isValid(id)) {
						msg(player, "&4Error: &cThere is no such prize id.");
						msg(player, "Type &b/vote redeem <prize id> <prize amount>");
						return true;
					}
					String strvotes = args[2];
					int votesNum;
					try {
						votesNum = Integer.parseInt(strvotes);
					} catch (Exception e) {
						msg(player, "&4Error: &cVote number is incorrect.");
						msg(player, "Type &b/vote redeem <prize id> <prize amount>");
						return true;
					}
					redeem(player, id, votesNum);
					return true;
				}
			} else if (arg.equalsIgnoreCase("stats")) {
				msg(player, head);
				msg(player, "&5Your stats:");
				msg(player, "Unredeemed votes: &a" + VoteSQL.getVotesNotRewarded(player.getName()));
				msg(player, "Donation credits: &a" + DonationCredit.getCredits(player.getName()));
				msg(player, "Total votes ever: &a" + VoteSQL.getAllPlayerVotes(player.getName()));
				msg(player, "Votes in last 24 hours: &a" + VoteSQL.getVotesLast24(player.getName()));
				msg(player, head);
				return true;
			} else if (arg.equalsIgnoreCase("complete")) {
				if (!redeemQueue.containsKey(player.getName())) {
					msg(player, "&4Error: &cYou do not have a pending prize request.");
					msg(player, "Type &b/vote redeem <prize id> <prize amount>");
					return true;
				}
				int id = Integer.parseInt(redeemQueue.get(player.getName()).split(";")[0]);
				int amount = Integer.parseInt(redeemQueue.get(player.getName()).split(";")[1]);
				redeemQueue.remove(player.getName());
				ArrayList<Vote> votes = VoteSQL.filterVotes(player.getName(), 0, null, true, false);
				int cost = VotePrize.getCost(id) * amount;
				int has = votes.size();
				if (cost > has) {
					msg(player, "&4Error: &cYou can't redeem a prize that costs " + cost + " votes, but only have " + has + " votes to spend.");
					return true;
				}
				if (id == 4 || id == 5) {
					msg(player, "&4Error: &cPrizes 4-5 have not been set up yet.");
					return true;
				}
				String name = VotePrize.getName(id).toLowerCase();
				if (name.equals("fly")) {
					if (player.hasPermission("fly.fly")) {
						msg(player, "&4Error: &cYou already have Premium! You don't need to pay votes for Fly Mode");
						return true;
					}
					if (!plugin.detectedServer().equals("survival")) {
						msg(player, "&4Error: &cFly Mode is only available on the Survival server");
						return true;
					}
				}
				if (name.equals("god")) {
					if (player.hasPermission("fairgod.fair")) {
						msg(player, "&4Error: &cYou already have Premium! You don't need to pay votes for God Mode");
						return true;
					}
					if (!plugin.detectedServer().equals("survival")) {
						msg(player, "&4Error: &cGod Mode is only available on the Survival server");
						return true;
					}
				}
				if (name.equals("creative")) {
					if (player.hasPermission("customplugin.creative")) {
						msg(player, "&4Error: &cYou already have DemiGod! You don't need to pay votes for Creative");
						return true;
					}
					if (!plugin.detectedServer().equals("survival")) {
						msg(player, "&4Error: &cCreative Mode is only available on the Survival server");
						return true;
					}
					int a = 0;
					for (ItemStack i : player.getInventory()) {
						if (i != null)
							a++;
					}
					boolean helm = (player.getInventory().getHelmet() != null);
					boolean ches = (player.getInventory().getChestplate() != null);
					boolean legg = (player.getInventory().getLeggings() != null);
					boolean boot = (player.getInventory().getBoots() != null);
					if (a > 0 || helm || ches || legg || boot) {
						msg(player, "&4Error: &cYou must clear your inventory completely to switch to creative mode.");
						return true;
					}
				}
				
				
				// ---- ----  REWARD SCRIPT  ---- ----
				
				//Pay Cost
				int voteCounter = 1;
				for (Vote vote : votes) {
					if (voteCounter <= cost) {
						vote.rewardVote(id);
					} else {
						break;
					}
					voteCounter++;
				}
				
				//Add to DB the reward
				int mins = VotePrize.getExtraVar(id)*amount;
				int expiretime = (int) (System.currentTimeMillis()/1000) + (60*mins);
				
				try {
					Statement st = (Statement) SQL.getConnection().createStatement(); 
					ResultSet result = st.executeQuery("SELECT * FROM `dd-voterewards` WHERE `player` = '" + player.getName() + "' && `expiretime` > '" + System.currentTimeMillis()/1000 + "';");

					while (result.next()) {
						int qid = result.getInt("prizeid");
						int qexpire = result.getInt("expiretime");
						if (qid == id) {
							expiretime = qexpire + (60*mins);
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				
				SQL.singleQuery("INSERT INTO `dd-voterewards`(`player`, `prizeid`, `expiretime`) VALUES ('" + player.getName() + "' , '" + id + "', '" + expiretime + "')");		
				
				msg(player, head);
				
				if (id <= 5) {
					Map<Integer, Integer> data = new HashMap<Integer, Integer>();
					if (rewardCache.containsKey(player)) {
						data = rewardCache.get(player);
					}
					data.put(id, expiretime);
					rewardCache.put(player.getName(), data);
				}
				
				if (name.equals("healing")) {
					double health = player.getHealth();
					health += VotePrize.getExtraVar(id);
					if (health > 20) 
						health = 20;
					player.setFoodLevel((int) health);
					msg(player, "You have been healed.");
				}
				if (name.equals("food")) {
					int foodLevel = player.getFoodLevel();
					foodLevel += VotePrize.getExtraVar(id);
					if (foodLevel > 20) 
						foodLevel = 20;
					player.setFoodLevel(foodLevel);
					msg(player, "You have been fed.");
				}
				if (name.equals("xp")) {
					player.giveExp(VotePrize.getExtraVar(id));
					msg(player, "You have been given &b" + VotePrize.getExtraVar(id) + "&6 XP.");
				}
				if (name.equals("fly")) {
					player.setAllowFlight(true);
					player.setFlying(true);
					msg(player, "You are now flying.");
				}
				if (name.equals("god")) {
					if (!plugin.fairGod.isGod(player)) {
						plugin.fairGod.toggleGod(player, true);
						msg(player, "You now have God mode.");
					}
				}
				if (name.equals("creative")) {
					player.setGameMode(GameMode.CREATIVE);
					msg(player, "You are now in creative.");
				}

				
				// ---- ----  END REWARD SCRIPT  ---- ----
				msg(player, "You now have &b" + VoteSQL.getVotesNotRewarded(player.getName()) + "&6 votes to spend.");
				msg(player, head);
				return true;
			} else {
				msg(player, "Command not found");
				return true;
			}
		}
	}
	
	Map<String, String> redeemQueue = new HashMap<String, String>();
	public void redeem(Player player, int id, int prizeamount) {
		int cost = VotePrize.getCost(id) * prizeamount;
		int has = VoteSQL.getVotesNotRewarded(player.getName());
		if (cost > has) {
			msg(player, "&4Error: &cYou can't redeem a prize that costs " + cost + " votes, but only have " + has + " votes to spend.");
			return;
		}
		msg(player, head);
		msg(player, "You are spending &a" + cost + "&6 votes for &a" + prizeamount + "&6 of the prize: &a" + VotePrize.getName(id));
		redeemQueue.put(player.getName(), id + ";" + prizeamount);
		msg(player, "Type &b/vote complete&6 to complete your spending");
		msg(player, head);
	}
	
	public void updateRewards() {
		Connection con = null;
		Map<String, Map<Integer, Integer>> temprewardCache = new HashMap<String, Map<Integer, Integer>>();
		try {
			con = SQL.getConnection();

			Statement st = (Statement) con.createStatement(); 
			ResultSet result = st.executeQuery("SELECT * FROM `dd-voterewards` WHERE `expiretime` > '" + System.currentTimeMillis()/1000 + "';");
			
			while (result.next()) {
				String player = result.getString("player");
				int prizeid = result.getInt("prizeid");
				int expire = result.getInt("expiretime");
				Map<Integer, Integer> data = new HashMap<Integer, Integer>();
				if (temprewardCache.containsKey(player)) {
					data = temprewardCache.get(player);
				}
				data.put(prizeid, expire);
				temprewardCache.put(player, data);
			}
		} catch (SQLException e1) {
			e1.printStackTrace();
			return;
		}
		updatePlayerRewardStatus(temprewardCache);
		rewardCache = temprewardCache;
	}
	
	private Map<String, Integer> generateData(Map<String, Map<Integer, Integer>> data) {
		Map<String, Integer> set = new HashMap<String, Integer>();
		for (String player : data.keySet()) {
			Map<Integer, Integer> prizeMap = data.get(player);
			for (int i : prizeMap.keySet()) {
				set.put(player + ";" + i, prizeMap.get(i));
			}
		}
		return set;  //RETURNS IN FORMAT: Name;PrizeId > TimeStamp
	}
	
	@SuppressWarnings("deprecation")
	public void updatePlayerRewardStatus(Map<String, Map<Integer, Integer>> tempSet) {
		Map<String, Integer> tempData = generateData(tempSet);
		Map<String, Integer> prevData = generateData(rewardCache);
		int now = (int) (System.currentTimeMillis()/1000);
		String server = plugin.detectedServer();

		for (String data : tempData.keySet()) {
			Player player = Bukkit.getPlayer(data.split(";")[0]);
			int prizeId = Integer.parseInt(data.split(";")[1]);
			String name = VotePrize.getName(prizeId).toLowerCase();

			if (player != null) {
				if (server.equals("survival")) {
					if (name.equals("fly")) {
						player.setAllowFlight(true);
					}
					if (name.equals("god")) {
						if (!plugin.fairGod.isGod(player)) {
							plugin.fairGod.toggleGod(player, true);
						}
					}
					if (name.equals("creative")) {
						player.setGameMode(GameMode.CREATIVE);
					}

					int prizeTime = tempData.get(data) - now;
//					if (prizeTime <= 10) {
//						msg(player, "You have 10 secs remaining for: " + VotePrize.getName(prizeId));
//					} else if (prizeTime <= 60) {
//						msg(player, "You have 1 min remaining for: " + VotePrize.getName(prizeId));
//					} else if (prizeTime <= 120) {
//						msg(player, "You have 2 mins remaining for: " + VotePrize.getName(prizeId));
//					} else if (prizeTime <= 300) {
//						msg(player, "You have 5 mins remaining for: " + VotePrize.getName(prizeId));
//					}
					if (prizeTime >= 60)
						msg(player, "You have &e" + (int)prizeTime/60 + "&6 mins remaining for: &a" + VotePrize.getName(prizeId));
					if (prizeTime < 60)
						msg(player, "You have &e" + ((int)prizeTime/5)*5 + "&6 secs remaining for: &a" + VotePrize.getName(prizeId));
					//Set player to be doing what their reward requests
					//Send reminders of when their reward will run out

				}
			} else {
				msg(player, "Go back to SV! Vote prize time is running out! (And you can't use those prizes in this world)");
			}
		}
		
		for (String data : prevData.keySet()) {
			if (!tempData.containsKey(data)) {
			Player player = Bukkit.getPlayer(data.split(";")[0]);
			int prizeId = Integer.parseInt(data.split(";")[1]);
			String name = VotePrize.getName(prizeId).toLowerCase();
				msg(player, "Your prize: &a" + VotePrize.getName(prizeId) + " &6has expired.");
				if (name.equals("fly")) {
					player.setFlying(false);
					player.setAllowFlight(false);
				}
				if (name.equals("god")) {
					if (!plugin.fairGod.isGod(player))
						plugin.fairGod.toggleGod(player, true);
				}
				if (name.equals("creative")) {
					player.getInventory().clear();
					player.getInventory().setHelmet(new ItemStack(0));
					player.getInventory().setChestplate(new ItemStack(0));
					player.getInventory().setLeggings(new ItemStack(0));
					player.getInventory().setBoots(new ItemStack(0));
					player.setGameMode(GameMode.SURVIVAL);
				}
				//If players not in tempData, set expired & msg
			}
		}
	}


	public void msg(CommandSender player, String msg) {
		if (player instanceof Player) {
			player.sendMessage(ChatColor.translateAlternateColorCodes("&".charAt(0), "&6" + msg.replaceAll("%name", player.getName())));
		} else {
			log(msg);
		}
	}

//	private void cmd(String player, String cmd) {
//		Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), cmd.replaceAll("%name", player));
//	}
	
	public void msg(String player, String msg) {
		ByteArrayOutputStream b = new ByteArrayOutputStream();
		DataOutputStream out = new DataOutputStream(b);
		 
		try {
			out.writeUTF("Message");
			out.writeUTF(player);
			out.writeUTF(ChatColor.translateAlternateColorCodes("&".charAt(0), "&6[&bDD&2Votes&6] " + msg));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		Player p = Bukkit.getOnlinePlayers()[0];
		 
		p.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
	}

	public void log(String info) {
		plugin.getLogger().info("<VoteRewards> " + info);
	}

} public class SkyBlockPortalReward {
	private CustomPlugin plugin;

	public SkyBlockPortalReward(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	@SuppressWarnings("deprecation")
	public void EntityPortalEnter(EntityPortalEnterEvent event) {
		if (event.getEntity().getLocation().getWorld().getName().equals("SkyBlock")) {
			if (event.getEntity() instanceof Player && getLowestBlock(event.getLocation().getBlock()).getData() != (byte) 2) {
				getLowestBlock(event.getLocation().getBlock()).setData((byte)2);
				((Player) event.getEntity()).getInventory().addItem(new ItemStack(Material.NETHERRACK, 20));
				((Player) event.getEntity()).getInventory().addItem(new ItemStack(Material.NETHER_BRICK, 3));
				((Player) event.getEntity()).getInventory().addItem(new ItemStack(Material.GLOWSTONE_DUST, 10));
				((Player) event.getEntity()).getInventory().addItem(new ItemStack(Material.GHAST_TEAR, 1));
				((Player) event.getEntity()).getInventory().addItem(new ItemStack(Material.SOUL_SAND, 15));
			}
		}
	}
	
	private Block getLowestBlock(Block block) {
		for (int y = block.getY()-1; y > block.getY()-4; y++) {
			Block b = block.getWorld().getBlockAt(block.getX(), y, block.getZ());
			if (b.getType().equals(Material.OBSIDIAN)) {
				return b;
			}
		}
		return block;
	}

	public void log(String info) {
		plugin.getLogger().info("<SkyBlockPortalReward> " + info);
	}
} public class SkyBlockTP {
	private CustomPlugin plugin;

	public SkyBlockTP(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	public void onPlayerInteract(PlayerInteractEvent event) { 
		Player player = event.getPlayer();
		if (event.getAction() == Action.PHYSICAL && event.getClickedBlock().getType() == Material.STONE_PLATE) {
			Location loc = event.getClickedBlock().getLocation();
			int x = loc.getBlockX();
			int z = loc.getBlockZ();
			if (z == 150 && x <= -2 && x >= -4) {
				Bukkit.dispatchCommand(player, "island");
			}
		}
	}

	public void log(String info) {
		plugin.getLogger().info("<SkyBlockTP> " + info);
	}
} public class DemiGodPackage implements Listener {
	private CustomPlugin plugin;
	private BlockLog bl = new BlockLog(plugin);
	private ArrayList<Material> disallowedBlocks = new ArrayList<Material>();
	private ArrayList<Material> unclickableBlocks = new ArrayList<Material>();
	private ArrayList<Material> unbreakableBlocks = new ArrayList<Material>();
	private ArrayList<String> disallowedCommands = new ArrayList<String>();
	
//	private Map<TNTPrimed, String> godTNT = new HashMap<TNTPrimed, String>();
//	private Map<Block, String> explodedBlocks = new HashMap<Block, String>();
//	private Map<Block, String> explodedBlockData = new HashMap<Block, String>();
	
	public DemiGodPackage(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		plugin.getServer().getPluginManager().registerEvents(this, plugin);
		populateDisallowedBlocks(); // Blocks you can't take out of inv
		populateUnclickableBlocks();// Blocks you can't open/right click
		populateUnbreakableBocks(); // Blocks you can't break
		populateDisallowedCommands();//Commands you can't type
//		startTntWatch();
		log("Enabled");
	}
	
	public void disable() {
		bl.saveLog();
//		if (explodedBlocks.size() > 0) {
//			Set<Block> set = explodedBlocks.keySet();
//			for (Block b : set) { //Loop through all logged exploded blocks
//				b.setTypeId(Integer.parseInt(explodedBlockData.get(b).split(";")[0]));
//				b.setData(Byte.parseByte(explodedBlockData.get(b).split(";")[1]));
//				if (b.getType().equals(Material.WALL_SIGN) || b.getType().equals(Material.SIGN_POST)) {
//					Sign sign = (Sign) b.getState();
//					sign.setLine(0, explodedBlockData.get(b).split(";")[2]);
//					sign.setLine(1, explodedBlockData.get(b).split(";")[3]);
//					sign.setLine(2, explodedBlockData.get(b).split(";")[4]);
//					sign.setLine(3, explodedBlockData.get(b).split(";")[5]);
//				}
//			}
//			explodedBlockData.clear();
//			explodedBlocks.clear();
//		}
	}

	public boolean creativeCommand(CommandSender sender, String[] args) {
		if (args.length > 0) {
			if (args[0].equalsIgnoreCase("save"))
				return onReloadCommand(sender, args);
		}
		if (!(sender instanceof Player)) {
			msg(sender, "You may NOT get creative mode. :P");
			return true;
		}
		Player p = (Player) sender;
		if (p.getWorld().getName().equals("Build") || p.getWorld().getName().equals("Destruction")) {
			if (p.getGameMode().equals(GameMode.CREATIVE)) {
				msg(p, "You are already in creative mode");
				return true;
			}
			p.setGameMode(GameMode.CREATIVE);
			return true;
		}
		
		
		if (!p.hasPermission("customplugin.creative")) {
			msg(p, "You must purchase the DemiGod class for this command.");
			return true;
		}
		if (p.getGameMode() == GameMode.CREATIVE) {
			msg(p, "You are already in Creative Mode! Try /survival");
			return true;
		}
		int a = 0;
		for (ItemStack i : p.getInventory()) {
			if (i != null)
				a++;
		}
		boolean helm = (p.getInventory().getHelmet() != null);
		boolean ches = (p.getInventory().getChestplate() != null);
		boolean legg = (p.getInventory().getLeggings() != null);
		boolean boot = (p.getInventory().getBoots() != null);
		if (a > 0 || helm || ches || legg || boot) {
			msg(p, "You must clear your inventory completely to switch to creative mode.");
			return true;
		}
		p.setGameMode(GameMode.CREATIVE);

		return true;
	}

	public boolean survivalCommand(CommandSender sender, String[] args) {
		if (!(sender instanceof Player)) {
			msg(sender, "Trying to troll?? NOT WORKING.");
			return true;
		}
		Player p = (Player) sender;

		if (p.getWorld().getName().equals("Build") || p.getWorld().getName().equals("Destruction")) {
			if (p.getGameMode().equals(GameMode.SURVIVAL)) {
				msg(p, "You are already in survival mode");
				return true;
			}
			p.setGameMode(GameMode.SURVIVAL);
			return true;
		}
		
		if (!p.hasPermission("customplugin.creative")) {
			msg(p, "You must purchase the DemiGod class for this command.");
			return true;
		}
		if (p.getGameMode() == GameMode.SURVIVAL) {
			msg(p, "You are already in Survival Mode! Try /creative");
			return true;
		}
		clearInv(p);

		return true;
	}
	
	@SuppressWarnings("deprecation")
	public void clearInv(Player p) { 
		p.getInventory().clear();
		p.getInventory().setHelmet(new ItemStack(0));
		p.getInventory().setChestplate(new ItemStack(0));
		p.getInventory().setLeggings(new ItemStack(0));
		p.getInventory().setBoots(new ItemStack(0));
		p.setGameMode(GameMode.SURVIVAL);
	}
	
	public boolean onReloadCommand(CommandSender sender, String[] args) {
		if (sender instanceof Player) {
			if (sender.isOp()) {
				bl.saveLog();
				msg(sender, "Creative BlockLog saved.");
			} else {
				msg(sender, "You do not have permission.");
			}
		} else {
			msg(sender, "Creative BlockLog saved.");
		}
		return true;
	}
	
	private boolean res(Player player) {
//		return player.getGameMode() == GameMode.CREATIVE && !player.isOp();
		return player.getGameMode() == GameMode.CREATIVE && (player.hasPermission("customplugin.creative.restrict") || (plugin.voteRewards.rewardCache.containsKey(player.getName()) && plugin.voteRewards.rewardCache.get(player.getName()).containsKey(3)));
//		return player.getGameMode() == GameMode.CREATIVE && player.hasPermission("customplugin.creative") && !player.isOp();
	}
	
	//================================================================================================================
	
	private void populateDisallowedBlocks() {
		disallowedBlocks.add(Material.BEDROCK);
		disallowedBlocks.add(Material.MONSTER_EGG);
		disallowedBlocks.add(Material.MONSTER_EGGS);
		disallowedBlocks.add(Material.ENCHANTED_BOOK);
		disallowedBlocks.add(Material.COMMAND);
		disallowedBlocks.add(Material.ENDER_PORTAL_FRAME);
		disallowedBlocks.add(Material.EYE_OF_ENDER);
		disallowedBlocks.add(Material.POTION);
		disallowedBlocks.add(Material.ITEM_FRAME);
		disallowedBlocks.add(Material.MINECART);
		disallowedBlocks.add(Material.SADDLE);
		disallowedBlocks.add(Material.BOAT);
		disallowedBlocks.add(Material.STORAGE_MINECART);
		disallowedBlocks.add(Material.POWERED_MINECART);
		disallowedBlocks.add(Material.FISHING_ROD);
		disallowedBlocks.add(Material.EXPLOSIVE_MINECART);
		disallowedBlocks.add(Material.HOPPER_MINECART);
		disallowedBlocks.add(Material.EXP_BOTTLE);
		disallowedBlocks.add(Material.LAVA_BUCKET);
		disallowedBlocks.add(Material.EGG);
		disallowedBlocks.add(Material.TNT);
	}
	
	private void populateUnclickableBlocks() { 
		unclickableBlocks.add(Material.CHEST);
		unclickableBlocks.add(Material.HOPPER);
		unclickableBlocks.add(Material.DISPENSER);
		unclickableBlocks.add(Material.DROPPER);
		unclickableBlocks.add(Material.FURNACE);
		unclickableBlocks.add(Material.BREWING_STAND);
		unclickableBlocks.add(Material.TRAPPED_CHEST);
		unclickableBlocks.add(Material.ENDER_CHEST);
		unclickableBlocks.add(Material.TNT);
	}
	
	private void populateUnbreakableBocks() {
		unbreakableBlocks.add(Material.BEDROCK);
	}
	
	private void populateDisallowedCommands() {
		disallowedCommands.add("/enderchest");
		disallowedCommands.add("/echest");
		disallowedCommands.add("/vc");
		disallowedCommands.add("/vchest");
		disallowedCommands.add("/virtualchest");
		disallowedCommands.add("/kit");
		disallowedCommands.add("/ekit");
	}
	
	//===============================================================================================================

	@EventHandler
	public void onPlayerDropItem(PlayerDropItemEvent event) {
		if (res(event.getPlayer())) {
			msg(event.getPlayer(), "You may not drop items in creative mode!");
			event.setCancelled(true);
		}
	}
	
	@EventHandler
	public void onPlayerPickupItem(PlayerPickupItemEvent event) {
		if (res(event.getPlayer())) {
			event.setCancelled(true);
		}
	}
	
	@EventHandler
	public void onPlayerDeathEvent(EntityDeathEvent event) {
		if (event.getEntity() instanceof Player) {
			Player player = (Player) event.getEntity();
			if (res(player)) {
				event.getDrops().clear();
			}
		}
	}
	
	@EventHandler
	public void onBlockPlace(BlockPlaceEvent event) {
		if (res(event.getPlayer())) {
			bl.write(event.getBlock(), event.getPlayer());
		}
	}
	
	@EventHandler 
	public void onBlockBreak(BlockBreakEvent event) {
		if (event.isCancelled())
			return;
		WorldGuardPlugin wg = plugin.getWorldGuard();
		boolean canBuild;
		if (wg == null) {
			canBuild = true;
		} else {
			canBuild = wg.canBuild(event.getPlayer(), event.getBlock());
		}
		if (bl.isLogged(event.getBlock()) && canBuild) {
			if (!res(event.getPlayer())) {
				msg(event.getPlayer(), "A creative mode player placed this block.");
			}
			event.setCancelled(true);
			event.getBlock().setType(Material.AIR);
			bl.remove(event.getBlock());
		}
	}
	
	@EventHandler
	public void onBlockPistonEvent(BlockPistonExtendEvent event) {
		for (Block b : event.getBlocks()) { 
			if (bl.isLogged(b)) {
				event.setCancelled(true);
//				animateBlock(b);
			}
		}
	}
	
	@EventHandler
	public void onBlockPistonContract(BlockPistonRetractEvent event) {
		if (event.getBlock().getType().equals(Material.PISTON_STICKY_BASE)) {
			if (!event.getBlock().getType().equals(Material.AIR))
				if (bl.isLogged(event.getBlock())) {
					event.setCancelled(true);
				}
		}
	}
	
//	private void animateBlock(final Block b) {
//		final Material type = b.getType();
//		plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
//			@Override 
//			public void run() {
//				b.setType(Material.REDSTONE_BLOCK);
//			}
//		}, 5);
//		plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
//			@Override 
//			public void run() {
//				b.setType(type);
//			}
//		}, 10);
//	}
	
//	@EventHandler
//	public void onBlocksFall(BlockPhysicsEvent event) {
////		if ((event.getBlock().getType().equals(Material.SAND) || event.getBlock().getType().equals(Material.GRAVEL)) && bl.isLogged(event.getBlock())) {
////			event.getBlock().setType(Material.AIR);
////			event.setCancelled(true);
//			bl.remove(event.getBlock());
////		}
//	}
	
	@SuppressWarnings("deprecation")
	@EventHandler
	public void onPlayerClick(InventoryClickEvent event) {
		if (res((Player) event.getWhoClicked())) {
//			log("Cursor: " + event.getCursor().getType().name());
//			log("CurrentItem: " + event.getCurrentItem().getType().name());
			if (event.getCurrentItem() != null) {
				if (disallowedBlocks.contains(event.getCurrentItem().getType())) {
					event.setCurrentItem(new ItemStack(Material.AIR));
					event.setCancelled(true);
				}
			}
			if (event.getCursor() != null) {
				if (disallowedBlocks.contains(event.getCursor().getType())) {
					event.setCancelled(true);
				}
			}
		}
		if (event.getWhoClicked().getGameMode().equals(GameMode.CREATIVE)) {
			if (event.getCurrentItem() != null) {
				if (event.getCurrentItem().getType().equals(Material.MONSTER_EGG)) {
					event.setCurrentItem(new ItemStack(Material.AIR));
					event.setCancelled(true);
				}
			}
			if (event.getCursor() != null) {
				if (event.getCursor().getType().equals(Material.MONSTER_EGG)) {
					event.setCursor(new ItemStack(Material.AIR));
					event.setCancelled(true);
				}
			}
		}
	}
	
	@EventHandler (priority = EventPriority.LOWEST)
	public void onPlayerInteract(PlayerInteractEvent event) {
		if (res(event.getPlayer())) {
			Block cB = event.getClickedBlock();
			if (cB != null) {
				if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
					if (unclickableBlocks.contains(cB.getType())) {
						event.setCancelled(true);
						msg(event.getPlayer(), "You may not use this block.");
					}
					if (cB.getType().equals(Material.WALL_SIGN) || cB.getType().equals(Material.SIGN_POST)) {
						final Sign sign = (Sign) cB.getState();
						if (sign.getLine(0).equals(ChatColor.DARK_BLUE + "[Buy]")) {
							sign.setLine(0, "");
							sign.update();
							plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
								@Override 
								public void run() {
									sign.setLine(0, ChatColor.DARK_BLUE + "[Buy]");
									sign.update();
								}
							}, 1);
						}
						if (sign.getLine(0).equals(ChatColor.DARK_BLUE + "[Sell]")) {
							sign.setLine(0, "");
							sign.update();
							plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
								@Override 
								public void run() {
									sign.setLine(0, ChatColor.DARK_BLUE + "[Sell]");
									sign.update();
								}
							}, 1);
						}
					}
				} else if (event.getAction() == Action.LEFT_CLICK_BLOCK) {
					if (unbreakableBlocks.contains(cB.getType())) {
						event.setCancelled(true);
						msg(event.getPlayer(), "You may not break this block.");
					}
				}
			}
		}

		if (event.isCancelled())
			return;
//		if (!event.getClickedBlock().getType().equals(Material.TNT))
//			return;
//		if (bl.isLogged(event.getClickedBlock())) {
//        	final Block tnt = event.getClickedBlock();
//        	final Player player = event.getPlayer();
//        	if (tnt.getWorld().getName().equals("Survival") || tnt.getWorld().getName().equals("PeaceWorld"))
//        	plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
//				@Override 
//				public void run() {
//					if (tnt.getType() != Material.AIR)
//						return;
//					if (player.getItemInHand() != null && player.getItemInHand().getType().equals(Material.FLINT_AND_STEEL)) {
//						log("LIT!");
//						bl.remove(tnt);
//						for (Entity possibleTNT : tnt.getWorld().getEntities()) {
//							if (possibleTNT instanceof TNTPrimed) {
//								TNTPrimed tntEnt = (TNTPrimed) possibleTNT;
//								log(tntEnt.getSource().toString());
//								if (tntEnt.getSource().equals(player)) {
//									godTNT.put(tntEnt, player.getName());
//									log(player.getName() + " just lit tnt at " + tntEnt.getLocation().toString());
//								}
//							}
//						}
//					}
//				}
//			}, 1);
//        }
	}
	
	@EventHandler
	public void onPlayerSendCommand(PlayerCommandPreprocessEvent event) {
		if (res(event.getPlayer())) {
			String command = event.getMessage().split(" ")[0];
			if (disallowedCommands.contains(command)) {
				event.setCancelled(true);
				msg(event.getPlayer(), "You may not type that command.");
			}
		}
	}
	
	@EventHandler (priority=EventPriority.LOWEST)
	public void onPlayerChangeWorld(PlayerChangedWorldEvent event) {
		if (res(event.getPlayer())) {
			clearInv(event.getPlayer());
		}
	}
	
	@EventHandler (priority=EventPriority.LOWEST)
	public void onPlayerQuitGame(PlayerQuitEvent event) {
		if (res(event.getPlayer())) {
			clearInv(event.getPlayer());
		}
	}
	
	@EventHandler
	public void onPlayerPunch(EntityDamageByEntityEvent event) {
		if (event.getDamager() instanceof Player && res((Player) event.getDamager())) {
			event.setCancelled(true);
		}
	}
	
	@EventHandler
	public void onPlayerTouchEntity(PlayerInteractEntityEvent event) {
		if (res(event.getPlayer())) {
			event.setCancelled(true);
		}
	}
	
//	@EventHandler
//	public void onTNTPrimeEvent (ExplosionPrimeEvent event) {
//		log("PRIMED");
//	}
	
//	@EventHandler
//	public void onRedstoneEvent (BlockRedstoneEvent event) {
//		final Block tnt = event.getBlock();
//		if (tnt.getType().equals(Material.TNT)) {
//			if (bl.isLogged(tnt)) {
//				log("TNT CURRENT: " + event.getNewCurrent());
//				plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
//					@Override 
//					public void run() {
//						if (tnt.getTypeId() != 0)
//							return;
//						log("LIT!");
//						bl.remove(tnt);
//						for (Entity possibleTNT : tnt.getWorld().getEntities()) {
//							if (possibleTNT instanceof TNTPrimed) {
//								TNTPrimed tntEnt = (TNTPrimed) possibleTNT;
//								log(tntEnt.getSource().toString());
//								godTNT.put(tntEnt, "REDSTONE");
//								log("REDSTONE just lit tnt at " + tntEnt.getLocation().toString());
//							}
//						}
//					}
//				}, 1);
//			}
//		}
//	}

//	@SuppressWarnings("deprecation")
//	@EventHandler
//	public void onExplodeEvent(EntityExplodeEvent event) {
//		log("EXPLODE");
//		
//		if (event.isCancelled())
//			return;
//		for (Block block : event.blockList()) {
//			if (bl.isLogged(block)) {
//				block.setType(Material.AIR);
//				bl.remove(block);
//			}
//			if (block.getType().equals(Material.TNT)) {
//				block.setType(Material.AIR);
//			}
//		}
//		if (event.getEntity() instanceof TNTPrimed) {
//			if (godTNT.keySet().contains(event.getEntity())) {
//				//			for (Block b : event.blockList()) {
//				//				if (b.getType().equals(Material.WALL_SIGN) || b.getType().equals(Material.SIGN_POST)) {
//				//					explodedBlocks.put(b, godTNT.get(event.getEntity()));
//				//					Sign sign = (Sign) b.getState();
//				//					String signData = ";" + sign.getLine(0) + ";" + sign.getLine(1) + ";" + sign.getLine(2) + ";" + sign.getLine(3);
//				//					explodedBlockData.put(b, b.getTypeId() + ";" + b.getData() + signData);
//				//					b.setTypeId(0);
//				//				}
//				//			}
//				for (Block b : event.blockList()) {
//					//				if (!(b.getType().equals(Material.WALL_SIGN) || b.getType().equals(Material.SIGN_POST))) {
//					explodedBlocks.put(b, godTNT.get(event.getEntity()));
//					explodedBlockData.put(b, b.getTypeId() + ";" + b.getData());
//					b.setType(Material.AIR);
//					//				}
//				}
//				godTNT.remove(event.getEntity());
//			}
//		}
//	}
	
//	private void startTntWatch() {
//		plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
//			@SuppressWarnings("deprecation")
//			@Override 
//			public void run() {
//				if (explodedBlocks.size() > 0) {
//					ArrayList<String> alreadyGened = new ArrayList<String>(); //This allows for several people to regen at the same time
//					ArrayList<Block> toRemove = new ArrayList<Block>();
//					Set<Block> set = explodedBlocks.keySet();
//					for (Block b : set) { //Loop through all logged exploded blocks
//						String playerName = explodedBlocks.get(b);
//						if (!alreadyGened.contains(playerName)) { //If the player hasn't already been covered
//							b = getLowestBlockPerPlayer(playerName);
////							int typeID = Integer.parseInt(explodedBlockData.get(b).split(";")[0]);
////							if (typeID == 63 || typeID == 68) {
////								if (typeID == 68) {
////									for (Block wallBlock : getPlayerBlocksExploded(playerName)) {
////										if (wallBlock.getLocation().distance(b.getLocation()) == 1) {
////											b = wallBlock;
////											typeID = Integer.parseInt(explodedBlockData.get(b).split(";")[0]);
////											if (typeID == 68) {
////												continue;
////											}
////										}
////									}
////								}
////								if (typeID == 68 || typeID == 68) {
////									Sign sign = (Sign) b.getState();
////									sign.setLine(0, explodedBlockData.get(b).split(";")[2]);
////									sign.setLine(1, explodedBlockData.get(b).split(";")[3]);
////									sign.setLine(2, explodedBlockData.get(b).split(";")[4]);
////									sign.setLine(3, explodedBlockData.get(b).split(";")[5]);
////									sign.update();
////								}
////							}
//							b.setTypeId(Integer.parseInt(explodedBlockData.get(b).split(";")[0]));
//							b.setData(Byte.parseByte(explodedBlockData.get(b).split(";")[1]));
//							alreadyGened.add(playerName);
//							explodedBlockData.remove(b);
//							toRemove.add(b);
//						}
//					}
//					for (Block b : toRemove) {
//						explodedBlocks.remove(b);
//					}
//				}
//			}
//		}, 20 * 10, 1);
//	}
	
//	private ArrayList<Block> getPlayerBlocksExploded(String p) {
//		ArrayList<Block> data = new ArrayList<Block>();
//		for (Block b : explodedBlocks.keySet()) {
//			if (explodedBlocks.get(b).equals(p)) {
//				data.add(b);
//			}
//		}
//		return data;
//	}
	
//	private Block getLowestBlockPerPlayer (String p) {
//		int lowest = 300;
//		Block block = null;
//		for (Block b : getPlayerBlocksExploded(p)) {
//			if (b.getLocation().getBlockY() < lowest) {
//				lowest = b.getLocation().getBlockY();
//				block = b;
//			}
//		}
//		return block;
//	}
	
	private void msg(CommandSender sender, String msg) {
		if (sender instanceof Player) {
			((Player) sender).sendMessage(ChatColor.DARK_RED + "["
					+ ChatColor.GOLD + "CREATIVE" + ChatColor.DARK_RED + "] "
					+ ChatColor.WHITE + ChatColor.translateAlternateColorCodes('&', msg));
		} else {
			log(msg);
		}
	}

	private void log(String info) {
		plugin.getLogger().info("<CreativeMode> " + info);
	}
} public class DirectionBook {
	private CustomPlugin plugin;
	
	public DirectionBook(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	ItemStack book = new ItemStack(Material.WRITTEN_BOOK);
	ItemStack sBook = new ItemStack(Material.WRITTEN_BOOK);
	ItemStack shovel = new ItemStack(Material.GOLD_SPADE);
	ItemStack stick = new ItemStack(Material.STICK);
	World griefFree;
	Location loc;
	Location adjLoc;
	Entity droppedBook = null;
	Entity droppedStick = null;
	Entity droppedShovel = null;
	ArrayList<Player> recieved = new ArrayList<Player>();
	
	public void enable() {
//		plugin.getServer().getPluginManager().registerEvents(this, plugin);
		plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
			@Override  
			public void run() {
				spawnBook(true);
			}
		}, 20 * 6, 20 * 10);
		writeBooks();
		log("Enabled");
	}
	
	public void writeBooks() {
		BookMeta bm = (BookMeta)book.getItemMeta();
		bm.setAuthor("DD Staff");
		bm.setTitle("How to claim land (Creative)");
		ArrayList<String> pages = new ArrayList<String>();
		pages.add(ChatColor.translateAlternateColorCodes('&', 
				"&1&lStep 1:\n&0Find an open area to build, or type '/plot auto' to find an open plot\n\n" + 
				"&1&lStep 2:\n&0Simply step in the square, type '/plot claim' and its yours."
			));
//		pages.add(ChatColor.translateAlternateColorCodes('&', 
//				"&1&lStep 3:\n&0Right click one corner of the location you want to build at. This will be a corner of the rectangular area you are claiming for yourself. A diamond block should show up, making it seen that you have selected that spot."
//			));
//		pages.add(ChatColor.translateAlternateColorCodes('&', 
//				"&1&lStep 4:\n&0Quickly (without removing the shovel from your hand) go to the other corner of the area you want to build in and right click the ground there. \nA rectangle of Gold and Glowstone should appear, this is your claim."
//			));
		pages.add(ChatColor.translateAlternateColorCodes('&',
				"&1&lClaiming Commands:\n" + 
				"&8'/plot claim'\n&0Claims your the plot you are in.\n\n" +
				"&8'/plot auto'\n&0Claims next available plot.\n\n" +
				"&8'/plot home[:#]'\n&0Get back to a plot.\n\n"
			));
		pages.add(ChatColor.translateAlternateColorCodes('&',
				"&1&lClaiming Commands:\n" + 
				"&8'/plot clear'\n&0RESETS the claim\n\n" +
				"&8'/plot add <player>'\n&0Lets another player build. &oSlightly glitchy\n\n" +
				"&8'/plot remove <player>'\n&0Disallows another player to build.\n\n"
				));
		pages.add(ChatColor.translateAlternateColorCodes('&',
				"&1&lClaiming Commands:\n" + 
				"&8'/plot dispose'\n&0RESETS and DELETES the claim\n\n" +
				"&8'/plot deny <player>'\n&0Denies player to enter your plot\n\n" +
				"&8'/plot undeny <player>'\n&0Allows player to enter your plot\n\n"
				));
		bm.setPages(pages);
		book.setItemMeta(bm);
		
		bm = (BookMeta)sBook.getItemMeta();
		bm.setAuthor("DD Staff");
		bm.setTitle("How to use Towny");
		pages = new ArrayList<String>();
		pages.add(ChatColor.translateAlternateColorCodes('&', 
				"&11. &0Travel to a location that is not inhabited yet.\n" +
				"&12. &0Right click with the stick to see any claims.\n" +
				"&13. &0Resize a claim by clicking the corners with the gold shovel.\n\n" +
				"&14. &8You can claim land manually with the steps on the next page:"
			));
		pages.add(ChatColor.translateAlternateColorCodes('&', 
				"&1&lStep 1:\n&0Determine your house size so you can get around to the corners of your property.\n\n" + 
				"&1&lStep 2:\n&0Take out the Golden Shovel, this is your claiming tool."
			));
		pages.add(ChatColor.translateAlternateColorCodes('&', 
				"&1&lStep 3:\n&0Right click one corner of the property you want to claim. This will be a corner of the rectangular area you are claiming for yourself. A diamond + should show up, making it seen that you have selected that spot."
			));
		pages.add(ChatColor.translateAlternateColorCodes('&', 
				"&1&lStep 4:\n&0Quickly (without removing the shovel from your hand) go to the other corner of the property and right click the ground there. \nA rectangle of Gold and Glowstone should appear, this is your claim."
			));
		pages.add(ChatColor.translateAlternateColorCodes('&',
				"&1&lClaiming Commands:\n" + 
				"&8'/abandonclaim'\n&0Deletes the claim you're standing in\n\n" +
				"&8'/trust <player>'\n&0Let other people build in your place\n\n" +
				"&8'/untrust <player>'\n&0Unallow trusted people from building in your claim\n\n"
			));
		pages.add(ChatColor.translateAlternateColorCodes('&',
				"&1&lClaiming Commands:\n" + 
				"&8'/accesstrust <player>'\n&0Lets a player use your buttons, levers, and beds\n\n" +
				"&8'/containertrust <player>'\n&0Lets a player use your buttons, levers, beds, crafting gear, containers, and animals.\n\n"
			));
		pages.add(ChatColor.translateAlternateColorCodes('&',
				"&1&lClaiming Commands:\n" + 
				"&8'/buyclaimblocks <#>'\n&0Converts server money to more claim blocks\n\n" +
				"&8'/sellclaimblocks <#>'\n&0Converts claim blocks to server money\n\n" +
				"&1If you want a visual demonstration, ask how to claim, &oa video link will appear."
				));
		bm.setPages(pages);
		sBook.setItemMeta(bm);
	}
	
//	@EventHandler
//	public void onPlayerOpenChest(PlayerInteractEvent event) {
//		Block chest = event.getClickedBlock();
//		if (chest != null && chest.getType().equals(Material.CHEST) && chest.getLocation().equals(loc)) {
//			((Chest) chest.getState()).getBlockInventory().clear();
//			((Chest) chest.getState()).getBlockInventory().addItem(book);
//		}
//	}
	
//	@EventHandler
//    public void StepOnPressurePlate(PlayerInteractEvent event){
//		if (event.getAction().equals(Action.PHYSICAL)){
//			Block plate = event.getClickedBlock();
//			if (plate.getTypeId() == 72 && plate.getLocation().equals(loc)){
//				PlayerInventory playerInv = event.getPlayer().getInventory();
//				playerInv.addItem(book);
//				if (!playerInv.contains(Material.GOLD_SPADE))
//					playerInv.addItem(shovel);
//				if (!playerInv.contains(Material.STICK))
//					playerInv.addItem(stick);
//			}
//		}
//	}
	
	public void spawnBook(final boolean check) {
		if (loc == null || griefFree == null) {
			griefFree = Bukkit.getWorld("TownWorld");
			loc = new Location(griefFree, 163, 77, 303);
			adjLoc = loc.clone().add(.5,.5,.5);
		} else {
			try {
				if (loc.getChunk() != null) {
					if (!loc.getChunk().isLoaded())
						loc.getChunk().load();
					plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
						@Override 
						public void run() {
							if (check && checkExisting()) {
								return;
							}
							try {
								loc.getBlock().setType(Material.WEB);
								griefFree.createExplosion(adjLoc.getX(), adjLoc.getY(), adjLoc.getZ(), (float) 3, false, false);
								plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
									@Override 
									public void run() {
										try {
											droppedBook = griefFree.dropItem(adjLoc, sBook);
											droppedShovel = griefFree.dropItem(adjLoc, shovel);
											droppedStick = griefFree.dropItem(adjLoc, stick);
										} catch (Exception e) {
											log("(2) Spawning the items failed...");
										}
									}
								}, 1);
								plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
									@Override 
									public void run() {
										try {
											loc.getBlock().setType(Material.AIR);
										} catch (Exception e) {
											log("(3) Spawning the items failed...");
										}
									}
								}, 2);
							} catch (Exception e) {
								log("(1) Spawning the items failed...");
							}
						}
					}, 20 * 5);
				}
			} catch (Exception e) {e.printStackTrace();}
		}
	}
	
	public boolean checkExisting() {
		try {
			for (Entity thing : loc.getChunk().getEntities()) {
				if (thing instanceof Item) {
					if (thing.getLocation().distance(loc) < 2 && ((Item) thing).getItemStack().getType() == Material.WRITTEN_BOOK) {
//						log("Found items. No need to respawn");
						return true;
					}
				}
			}
		} catch (Exception e) {
			log("Couldn't find the items before spawning!");
		}
		return false;
	}
	
//	@EventHandler
	public void onPlayerPickupBook(PlayerPickupItemEvent event) {
		final Player player = event.getPlayer();
		if (player.getWorld().equals(griefFree)) {
			Item drop = event.getItem();
			if (drop.equals(droppedBook) || drop.equals(droppedShovel) || drop.equals(droppedStick)) {
//				PlayerInventory playerInv = player.getInventory();
				if (!recieved.contains(player)) {
					if (drop.equals(droppedBook)) {
						spawnBook(false);
						plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
							@Override 
							public void run() {
								recieved.add(player);
							}
						}, 2);
					}
				} else {
					event.setCancelled(true);
				}
			}
		}
	}
	
//	@EventHandler
	public void onDropsDespawn(ItemDespawnEvent event) {
		Entity item = event.getEntity();
		if (item.equals(droppedBook) || item.equals(droppedShovel) || item.equals(droppedStick)) {
			event.setCancelled(true);
			log("Renewing item");
		}
	}
	
//	@EventHandler
	public void onPlayerDropItem(final PlayerDropItemEvent event) {
		if (event.getItemDrop().getItemStack().equals(sBook)) {
			event.setCancelled(true);
			plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
				@Override 
				public void run() {
					if (event.getPlayer().getInventory().getItemInHand().equals(sBook))
					event.getPlayer().getInventory().setItemInHand(new ItemStack(Material.AIR));
				}
			}, 1);
		}
	}
	
//	@EventHandler
	public void onPlayerChangeWorld(PlayerChangedWorldEvent event) {
		Player player = event.getPlayer();
		if (player.getWorld().getName().equals("Build")) {
			Inventory playerInv = player.getInventory();
			if (!playerInv.contains(book))
				playerInv.addItem(book);
		}
		if (player.getWorld() == griefFree) {
			spawnBook(true);
//			player.getWorld().spawnEntity(player.getLocation().add(0, 5, 0), EntityType.FIREWORK);
		}
	}
	
	public void log(String info) {
		plugin.getLogger().info("<DirectionBook> " + info);
	}
} public class DonorShop {
	private CustomPlugin plugin;
	
	private Map<Player, Boolean> going = new HashMap<Player, Boolean>();
	private Location donorBlock;
	private Location pressurePlate;
	
	private Map<Player, Integer> tasks = new HashMap<Player, Integer>();
	private Map<Player, Long> timeout = new HashMap<Player, Long>();
	
	public DonorShop(CustomPlugin plugin) {
		this.plugin = plugin;
	}
	
	public void enable() {
		donorBlock = new Location(Bukkit.getWorld("Survival"), 123.5, 75.5, 198.5);
		pressurePlate = new Location(Bukkit.getWorld("Survival"), 94, 200, 198);
		log("Enabled");
	}
	
	@SuppressWarnings("deprecation")
	public void disable() {
		for (Block b : exploded.keySet()) {
			b.setTypeId(Integer.parseInt(exploded.get(b).split(";")[0]));
			b.setData(Byte.parseByte(exploded.get(b).split(";")[1]));
		}
		if (tnt != null)
			tnt.remove();
	}
	
	private ArrayList<Player> queued = new ArrayList<Player>();
	public void onPlayerMoveEvent(PlayerMoveEvent event) {
		if (event.getPlayer().getWorld().equals(donorBlock.getWorld())) {
			Player player = event.getPlayer();
			Location pLoc = player.getLocation();
			if (!player.hasPermission("customplugin.donorshop"))
				return;
			if (pLoc.distance(donorBlock) < 1.5 && !queued.contains(player)) {
				msg(player, "Punch the quartz below to go to the donor shop.");
				queued.add(player);
			} else if (pLoc.distance(pressurePlate) < 1.5 && !queued.contains(player)) {
				msg(player, "Sneak on the pressure plate to return to spawn.");
				queued.add(player);
			} else if (pLoc.distance(pressurePlate) >= 1.5 && pLoc.distance(donorBlock) >= 1.5 && queued.contains(player)) {
				queued.remove(player);
			}
			if (going.containsKey(player) && !pLoc.getWorld().equals(donorBlock.getWorld())) {
				removePlayer(player);
				msg(player, "WHY ARE YOU IN ANOTHER WORLD! YOU WERE ABOUT TO GO FLYING UP!");
				return;
			}
			if (going.containsKey(player) && going.get(player)) {
				Location pLevelLoc = donorBlock.clone();
				pLevelLoc.setY(pLoc.getY());
				double dis = pLoc.distance(pLevelLoc);
				if (dis > 1.5) { // if the player is out of the scope that brings them up, this stops them
					pLoc.setX(donorBlock.getX());
					pLoc.setZ(donorBlock.getZ());
					player.teleport(pLoc);
				}
				if (pLoc.getY() < donorBlock.getY()) {
					pLoc.setY(donorBlock.getY());
					player.teleport(pLoc);
				}
				
				if (pLoc.getY() > 194) {
					removePlayer(player);
					player.setVelocity(new Vector(-1, .5, 0));
					msg(player, "Welcome to the Donor Shop!");
				} else {
					player.setVelocity(new Vector(0, 1.5, 0));
					player.getWorld().playEffect(player.getLocation(), Effect.MOBSPAWNER_FLAMES, 50);
				}
			}
		}
	}
	
	@SuppressWarnings("deprecation")
	private void removePlayer(Player player) {
		for (Block b : exploded.keySet()) {
			b.setTypeId(Integer.parseInt(exploded.get(b).split(";")[0]));
			b.setData(Byte.parseByte(exploded.get(b).split(";")[1]));
		}
		exploded.clear();
		if (tnt != null) {
			tnt.remove();
			tnt = null;
		}
		going.remove(player);
	}
	
	private Entity tnt = null;
	
	public void onPlayerPunchBlock(PlayerInteractEvent event) {
		if (event.getClickedBlock() != null) {
			if (event.getClickedBlock().equals(donorBlock.getBlock())) {
				final Player player = event.getPlayer();
				if (!player.hasPermission("customplugin.donorshop"))
					return;
				if (exploded.size() > 0 || tnt != null) {
					msg(player, "A transport is already commencing! Wait a bit.");
					return;
				}
				msg(player, "Transport Commencing!");
				going.put(player, false);
				tnt = donorBlock.getWorld().spawnEntity(donorBlock.clone().add(0,11,0), EntityType.PRIMED_TNT);
				plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
					@Override 
					public void run() {
						if (going.containsKey(player)) {
							going.put(player, true);
							player.setVelocity(new Vector(0, 2, 0));
						}
					}
				}, 5 * 17);
			}
		}
	}
	
	
	
	/*
	 * Further code is from the DrukenWizard (Code to tp back)
	 */
	
	private void attemptTeleport(final Player player) {
		player.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 20*10, 1000));
//		player.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION, 20*10, 50));
		player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 20*10, 1));
		int task = plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
			@Override 
			public void run() {
				tpPlayer(player);
			}
		}, 20*5);
		tasks.put(player, task);
	}
	
	private void cancelTeleport(Player player) {
		if (tasks.containsKey(player)) {
			Bukkit.getScheduler().cancelTask(tasks.get(player));
			tasks.remove(player);
		}
		removeEffects(player);
		msg(player, "Keep sneaking to reach the spawn.");
	}
	
	private void tpPlayer(Player player) {
		for (int a = 0; a < 50; a++)
			player.getWorld().playEffect(player.getLocation(), Effect.MOBSPAWNER_FLAMES, 0);
		player.teleport(new Location(donorBlock.getWorld(), donorBlock.getX(), donorBlock.getY() + 1, donorBlock.getZ(), player.getLocation().getYaw(), player.getLocation().getPitch()));
		for (int a = 0; a < 20; a++)
			player.getWorld().playEffect(player.getLocation(), Effect.MOBSPAWNER_FLAMES, 0);
		timeout.put(player, System.currentTimeMillis()/1000);
		removeEffects(player);
	}
	
	private void removeEffects(Player player) {
		player.removePotionEffect(PotionEffectType.CONFUSION);
		player.removePotionEffect(PotionEffectType.BLINDNESS);
//		player.removePotionEffect(PotionEffectType.NIGHT_VISION);
	}
	
	public void onPlayerSneaks(PlayerToggleSneakEvent e) {
		Player player = e.getPlayer();
		if (player.getLocation().getBlock().equals(pressurePlate.getBlock())) {
			if (timeout.containsKey(player)) {
				if (timeout.get(player) + 5 > System.currentTimeMillis()/1000)
					return;
			}
			if (e.isSneaking()) {
				attemptTeleport(player);
			} else {
				cancelTeleport(player);
			}
		}
	}
	
	/*
	 * Events for the DonorShop tp
	 */
	
	public Map<Block, String> exploded = new HashMap<Block, String>();
	
	@SuppressWarnings("deprecation")
	public void onTntExplodeEvent(EntityExplodeEvent event) {
		if (tnt != null && event.getEntity().equals(tnt)) {
			for (Block b : exploded.keySet()) {
				b.setTypeId(Integer.parseInt(exploded.get(b).split(";")[0]));
				b.setData(Byte.parseByte(exploded.get(b).split(";")[1]));
			}
			exploded.clear();
			for (Block b : event.blockList()) {
				exploded.put(b, b.getTypeId() + ";" + b.getData());
				b.setTypeId(0);
			}
			event.setCancelled(false);
			tnt = null;
		}
	}
	
	public void onPlayerTeleportEvent(PlayerTeleportEvent event) {
		if (!event.getPlayer().hasPermission("customplugin.donorshop")) {
			if (event.getTo().getWorld().equals(donorBlock.getWorld())) {
			if (event.getTo().distance(new Location(donorBlock.getWorld(), 104, 199, 198)) < 30) {
				event.setCancelled(true);
				msg(event.getPlayer(), "YOU may not teleport to the donor shop!");
			}
			}
		}
		if (going.containsKey(event.getPlayer())) {
			removePlayer(event.getPlayer());
			msg(event.getPlayer(), "Your teleportation has been cancelled");
		}
	}
	
	public void onPlayerChangeWorld(PlayerChangedWorldEvent event) {
		if (going.containsKey(event.getPlayer())) {
			removePlayer(event.getPlayer());
			msg(event.getPlayer(), "Don't mess with the system!");
		}
	}
	
	public void onPlayerQuitEvent(PlayerQuitEvent event) {
		if (going.containsKey(event.getPlayer())) {
			removePlayer(event.getPlayer());
		}
	}
	
	public void msg(Player p, String msg) {
		p.sendMessage("[" + ChatColor.GOLD + "DonorShop" + ChatColor.WHITE + "] " + ChatColor.AQUA + msg);
	}
	
	public void log(String info) {
		plugin.getLogger().info("<DonorShop> " + info);
	}
} public class EndDragonRespawn {
	
	private CustomPlugin plugin;
	
	public EndDragonRespawn(CustomPlugin plugin) {
		this.plugin = plugin;
	}
	
	private World End;
	
	private ArrayList<String> crystalLocations = new ArrayList<String>();
	
	@SuppressWarnings("deprecation")
	public void enable() {
		log("Enabling...");
//		plugin.getServer().getPluginManager().registerEvents(this, plugin);
		plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
			@Override 
			public void run() {
				End = Bukkit.getWorld("End");
				if (End == null) {
					plugin.getLogger().warning("No End world found!");
				}
			}
		}, 5 * 20);
		plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
			@Override  
			public void run() {
				scanEnd(false);
			}
		}, 20 * 6, 20 * 60);
		log("Searching for End shortly.");
		
		crystalLocations.add("-8,70,15");
		crystalLocations.add("-26,75,20");
		crystalLocations.add("-26,93,31");
		crystalLocations.add("-66,77,62");
		crystalLocations.add("-43,81,69");
		crystalLocations.add("-42,74,114");
		crystalLocations.add("-30,72,96");
		crystalLocations.add("-11,82,119");
		crystalLocations.add("-2,83,80");
		crystalLocations.add("29,94,65");
		crystalLocations.add("58,85,50");
		crystalLocations.add("50,78,13");
		crystalLocations.add("60,89,-2");
		crystalLocations.add("92,79,5");
		crystalLocations.add("72,97,-6");
		crystalLocations.add("75,74,-38");
		crystalLocations.add("32,82,-83");
		crystalLocations.add("6,76,-37");
		crystalLocations.add("-11,81,-82");
		crystalLocations.add("-46,91,-66");
		crystalLocations.add("-53,88,-30");
		crystalLocations.add("-41,71,-20");
		crystalLocations.add("-101,82,-8");

		log("Enabled");
	}
	
	public void scanEnd(final boolean spawnNew) {
		if (End == null) {
			End = Bukkit.getWorld("End");
		} else {
			Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
				public void run() {
					boolean found = false;
					ArrayList<Location> foundCrystals = new ArrayList<Location>();
					for (Chunk chunk : End.getLoadedChunks()) {
						for (Entity e : chunk.getEntities()) {
							if (e instanceof EnderDragon) {
								if (found)
									e.remove();
								found = true;
							}
							if (e instanceof EnderCrystal) {
								boolean cfound = false;
								for (Location l : foundCrystals) {
									if (e.getLocation().distance(l) < 3) {
										e.remove();
										cfound = true;
										continue;
									}
								}
								if (!cfound) {
									foundCrystals.add(e.getLocation());
								}
							}
						}
					}
					if (!found && spawnNew) {
						Location loc = new Location(End, 0, 85, -1.5);
						End.spawnEntity(loc, EntityType.ENDER_DRAGON);
						respawnEnderCrystals();
						plugin.getServer().broadcastMessage(ChatColor.BLACK + "[" + ChatColor.DARK_RED + "EndDragonRespawn" + ChatColor.BLACK + "]" + ChatColor.RED + " The dragon has resurrected!");
						log("EnderDragon Respawned!");
					} else {
						if (spawnNew)
							log("Dragon found. No need to respawn.");
					}
				}
			}, 200L);
		}
	}
	
	public void respawnEnderCrystals() {
		for (String strLoc : crystalLocations) {
			String[] strL = strLoc.split(",");
			Location loc = new Location(End, Integer.parseInt(strL[0]) + .5, Integer.parseInt(strL[1]), Integer.parseInt(strL[2]) + .5);
			boolean pre = false;
			for (Entity e : End.getEntities()) {
				if (e instanceof EnderCrystal) {
					if (e.getLocation().distance(loc) < 3) {
						pre = true;
						break;
					}
				}
			}
			if (pre)
				continue;
			loc.getBlock().setType(Material.BEDROCK);
			End.spawnEntity(loc, EntityType.ENDER_CRYSTAL);
			Location search = loc.clone();
			search.add(0, -1, 0);
			while (!End.getBlockAt(search).getType().equals(Material.BEDROCK)) {
				search.add(0, -1, 0);
//				log(search.getBlock().getType().toString());
				if (search.getBlockY() <= 1) {
					log("ERROR! SPAWN CRYSTAL AT: " + strLoc + " DOES NOT HAVE BEDROCK.");
					break;
				}
			}
			if (search.getBlockY() <= 1) {
				continue;
			}
			ArrayList<Location> bedrockLayer = new ArrayList<Location>();
			for (int x = search.getBlockX() - 3; x <= search.getBlockX() + 3; x++) {
				for (int z = search.getBlockZ() - 3; z <= search.getBlockZ() + 3; z++) {
					Location l = new Location(End, x, search.getY(), z);
					if (l.getBlock().getType().equals(Material.BEDROCK)) {
						bedrockLayer.add(l);
					}
				}
			}
			for (Location l : bedrockLayer) {
				for (int y = l.getBlockY() + 1; y < loc.getBlockY(); y++) {
					Block b = End.getBlockAt(l.getBlockX(), y, l.getBlockZ());
					if (!b.getType().equals(Material.OBSIDIAN)) 
						b.setType(Material.OBSIDIAN);
				}
			}
		}
	}
	
//	@EventHandler
	public void onPlayerGoesToEnd(PlayerChangedWorldEvent event) {
		Player player = event.getPlayer();
		if (!player.getWorld().getEnvironment().equals(World.Environment.THE_END))
			return;
		scanEnd(true);
	}
	
//	@EventHandler
	@SuppressWarnings("deprecation")
	public void onDragonCreatesPortal(EntityCreatePortalEvent event)
	{
		if (event.isCancelled())
			return;
		
		Entity entity = event.getEntity();

		if (!(entity instanceof EnderDragon))
			return;
		
		log("The dragon has been killed!");
		
		Location enderEggLoc = entity.getLocation();
		
		if (enderEggLoc != null) {
			End.getBlockAt(enderEggLoc).setTypeId(122);
		} else {
			log("Failed to process portal, cancelling event anyway!");
		}
		event.setCancelled(true);
	}
	
	public void log(String info) {
		plugin.getLogger().info("<EndDragonRespawn> " + info);
	}
	
} public class EnderEggCollection {
	private CustomPlugin plugin;

	public EnderEggCollection(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	public void onPlayerInteract(PlayerInteractEvent event) { 
		final Player player = event.getPlayer();
		if (player.getWorld().getName().equals("End")) {
			Block egg = event.getClickedBlock();
			if (egg != null && egg.getType() == Material.DRAGON_EGG) {
				event.setCancelled(true);
				egg.setType(Material.AIR);
				final Location eggLoc = egg.getLocation();
				player.getWorld().strikeLightning(eggLoc.clone().add(0,0,2));
				player.getWorld().strikeLightning(eggLoc.clone().add(0,0,-2));
				player.getWorld().strikeLightning(eggLoc.clone().add(2,0,0));
				player.getWorld().strikeLightning(eggLoc.clone().add(-2,0,0));
				plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
					@Override 
					public void run() {
						Item eggDrop = player.getWorld().dropItemNaturally(eggLoc, new ItemStack(Material.DRAGON_EGG));
						eggDrop.setVelocity(new Vector(0,0,0));
					}
				}, 20);
			}
		}
	}

	public void log(String info) {
		plugin.getLogger().info("<EnderEggCollection> " + info);
	}
} public class ExtraMiningLoot {
	private CustomPlugin plugin;

	public ExtraMiningLoot(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	@SuppressWarnings("deprecation")
	public void onPlayerBreakBlock(BlockBreakEvent e) {
		if (!e.isCancelled()) {
			if (!(e.getBlock().getType() != Material.DIAMOND_ORE || e.getPlayer().getGameMode().equals(GameMode.CREATIVE)))
				if (e.getBlock().getData() == 0) {
					e.setExpToDrop(100);
					e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation(), new ItemStack(Material.DIAMOND, 4));
				}
		}
	}
	
	@SuppressWarnings("deprecation")
	public void onPlayerPlaceBlock(BlockPlaceEvent e) {
		if (e.getBlock().getType() == Material.DIAMOND_ORE && !e.isCancelled())
			e.getBlock().setData((byte) 1);
	}

	public void log(String info) {
		plugin.getLogger().info("<ExtraMiningLoot> " + info);
	}
} public class FairFly {
	private CustomPlugin plugin;

	public FairFly(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}

	public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args)
	{
		if (cmd.getName().equalsIgnoreCase("fly")) {
			if ((sender instanceof Player)) {
				Player player = (Player)sender;
				if (args.length == 0) {
					if (player.hasPermission("fly.fly"))
						if (player.getAllowFlight()) {
							player.setFlying(false);
							player.setAllowFlight(false);
							player.sendMessage(ChatColor.GOLD + "You were put out of fly mode.");
						} else {
							player.setAllowFlight(true);
							player.setFlySpeed(0.1F);
							player.sendMessage(ChatColor.GOLD + "You were put into fly mode.");
						}
				}
				else if (args.length == 1) {
					if (player.hasPermission("fly.other")) {
						Player otherplayer = Bukkit.getPlayer(args[0]);
						if (otherplayer != null) {
							if (otherplayer.getAllowFlight()) {
								otherplayer.setFlying(false);
								otherplayer.setAllowFlight(false);
								otherplayer.sendMessage(ChatColor.GOLD + "You were put out of fly mode.");
								player.sendMessage(args[0] + 
										" was put out of fly mode!");
							} else {
								otherplayer.setAllowFlight(true);
								otherplayer.setFlySpeed(0.1F);
								otherplayer.sendMessage(ChatColor.GOLD + "You were put into fly mode.");
								player.sendMessage(args[0] + 
										" was sent to sky!");
							}
						}
						else player.sendMessage(args[0] + 
								" is not online or doesn't exist!");
					}
				}
				else {
					return false;
				}
			} else {
				if (args.length == 1) {
					Player otherplayer = Bukkit.getPlayer(args[0]);
					if (otherplayer != null) {
						if (otherplayer.getAllowFlight()) {
							otherplayer.setFlying(false);
							otherplayer.setAllowFlight(false);
							otherplayer.sendMessage(ChatColor.GOLD + "You were put out of fly mode.");
							log(args[0] + " was put out of fly mode!");
						} else {
							otherplayer.setAllowFlight(true);
							otherplayer.setFlySpeed(0.1F);
							otherplayer.sendMessage(ChatColor.GOLD + "You were put into fly mode.");
							log(args[0] + " was sent to sky!");
						}
					}
					else log(args[0] + " is not online or doesn't exist!");
				} else {
					log("Console's can't fly!!!!!!");
				}
			}
			return true;
		}if (cmd.getName().equalsIgnoreCase("flyspeed")) {
			Player player = (Player)sender;
			if ((sender instanceof Player)) {
				if (args.length == 0)
					return false;
				if (args.length == 1) {
					int speed = 1;
					try {
						speed = Integer.parseInt(args[0]);
					} catch (NumberFormatException e) {
						player.sendMessage("Only integer values are allowed here");
						return true;
					}

					if ((player.hasPermission("fly.speed") | player.hasPermission("fly.speed.10"))) {
						if ((speed < -10) || (speed > 10)) {
							player.sendMessage("Speed can't be less than -10 or more than 10");
						} else {
							player.setFlySpeed(speed / 10.0F);
							player.sendMessage("Flyspeed set to " + speed);
						}
						return true;
					}if (player.hasPermission("fly.speed.9")) {
						if ((speed <= 9) && (speed >= -9)) {
							player.setFlySpeed(speed / 10.0F);
							player.sendMessage("Flyspeed set to " + speed);
						} else {
							player.sendMessage("You don't have permission to do that");
						}
						return true;
					}if (player.hasPermission("fly.speed.8")) {
						if ((speed <= 8) && (speed >= -8)) {
							player.setFlySpeed(speed / 10.0F);
							player.sendMessage("Flyspeed set to " + speed);
						} else {
							player.sendMessage("You don't have permission to do that");
						}
						return true;
					}if (player.hasPermission("fly.speed.7")) {
						if ((speed <= 7) && (speed >= -7)) {
							player.setFlySpeed(speed / 10.0F);
							player.sendMessage("Flyspeed set to " + speed);
						} else {
							player.sendMessage("You don't have permission to do that");
						}
						return true;
					}if (player.hasPermission("fly.speed.6")) {
						if ((speed <= 6) && (speed >= -6))
							player.setFlySpeed(speed / 10.0F);
						else {
							player.sendMessage("You don't have permission to do that");
						}
						return true;
					}if (player.hasPermission("fly.speed.5")) {
						if ((speed <= 5) && (speed >= -5)) {
							player.setFlySpeed(speed / 10.0F);
							player.sendMessage("Flyspeed set to " + speed);
						} else {
							player.sendMessage("You don't have permission to do that");
						}
						return true;
					}if (player.hasPermission("fly.speed.4")) {
						if ((speed <= 4) && (speed >= -4)) {
							player.setFlySpeed(speed / 10.0F);
							player.sendMessage("Flyspeed set to " + speed);
						} else {
							player.sendMessage("You don't have permission to do that");
						}
						return true;
					}if (player.hasPermission("fly.speed.3")) {
						if ((speed <= 3) && (speed >= -3)) {
							player.setFlySpeed(speed / 10.0F);
							player.sendMessage("Flyspeed set to " + speed);
						} else {
							player.sendMessage("You don't have permission to do that");
						}
						return true;
					}if (player.hasPermission("fly.speed.2")) {
						if ((speed <= 2) && (speed >= -2)) {
							player.setFlySpeed(speed / 10.0F);
							player.sendMessage("Flyspeed set to " + speed);
						} else {
							player.sendMessage("You don't have permission to do that");
						}
						return true;
					}
					player.sendMessage("You don't have permission to do that");

					return true;
				}
			}
		}

		return false;
	}

	//Flying player attacks another player
	public void onHit(EntityDamageByEntityEvent event)
	{
		if ((event.getDamager() instanceof Player)) {
			Player damager = (Player)event.getDamager();
			if (damager.getAllowFlight()) { //if punch player and they have FLY ENABLED
				if ((damager.isFlying()) && (!damager.hasPermission("Fly.damage")) && (damager.getGameMode() != GameMode.CREATIVE))
					event.setCancelled(true);

				if (!damager.isFlying() && event.getEntity() instanceof Player && damager.getGameMode() != GameMode.CREATIVE) {
					damager.setFlying(false);
					damager.setAllowFlight(false);
					damager.sendMessage(ChatColor.GOLD + "You were put out of fly mode.");
				}
			}
		}
	}

	//Flying player takes damage
	public void onDamage(EntityDamageEvent event)
	{
		if ((event.getEntity() instanceof Player)) {
			Player receiver = (Player)event.getEntity();
			if ((receiver.isFlying()) && (receiver.hasPermission("Fly.invincible")))
				event.setCancelled(true);
		}
	}

	//Flying player tries to shoot a bow
	@SuppressWarnings("deprecation")
	public void onShoot(EntityShootBowEvent event)
	{
		if ((event.getEntity() instanceof Player)) {
			Player archer = (Player)event.getEntity();
			if (archer.getAllowFlight()) {
				if ((archer.isFlying()) && (!archer.hasPermission("Fly.damage")) && 
						(archer.getGameMode() != GameMode.CREATIVE)) {
					event.setCancelled(true);
					archer.updateInventory();
				}
				if (!archer.isFlying() && archer.getGameMode() != GameMode.CREATIVE) {
					archer.setFlying(false);
					archer.setAllowFlight(false);
					archer.sendMessage(ChatColor.GOLD + "You were put out of fly mode.");
				}
			}
		}
	}

	public void log(String info) {
		plugin.getLogger().info("<FairFly> " + info);
	}
} public class FairGod {
	
	public CustomPlugin plugin;
	
	public FairGod(CustomPlugin plugin) {
		this.plugin = plugin;
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Map<String, Boolean> gods = new HashMap();

	public void enable()
	{
//		plugin.getServer().getPluginManager().registerEvents(this, plugin);
		log("Enabled");
	}
	
	public boolean godCommand(CommandSender sender, String[] args)
	{
		Player player = null;
		if ((sender instanceof Player))
		{
			player = (Player)sender;
		}
		else
		{
			log("You must be a player to use that command!");
			return true;
		}

		if (args.length == 0)
		{
			if (player.hasPermission("fairgod.fair"))
			{
				toggleGod(player, true);
				return true;
			}

			player.sendMessage(ChatColor.RED + "You don't have permission to do that!");
			return true;
		}

		return false;
	}

	public boolean toggleGod(Player player, boolean fair)
	{
		if (this.gods.containsKey(player.getName()))
		{
			this.gods.remove(player.getName());
			player.sendMessage(ChatColor.GOLD + "You are now out of God mode.");

			return true;
		}

		this.gods.put(player.getName(), Boolean.valueOf(fair));
		player.sendMessage(ChatColor.GOLD + "You are now in God mode.");

		if (!fair)
		{
			player.sendMessage(ChatColor.GOLD + "You are in unfair mode! You may harm other players.");
		}
		return false;
	}

	public boolean isGod(Player player)
	{
		if (this.gods.containsKey(player.getName()))
		{
			return true;
		}

		return false;
	}

	public boolean isFair(Player player)
	{
		return ((Boolean)this.gods.get(player.getName())).booleanValue();
	}

//	public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args)
//	{
//		if (commandLabel.equalsIgnoreCase("god")) {
//			log("Recieved Command");
//			Player player = null;
//			if ((sender instanceof Player))
//			{
//				player = (Player)sender;
//			}
//			else
//			{
//				log("You must be a player to use that command!");
//				return true;
//			}
//
//			if (args.length == 0)
//			{
//				if (player.hasPermission("fairgod.fair"))
//				{
//					toggleGod(player, true);
//					return true;
//				}
//
//				player.sendMessage(ChatColor.RED + "You don't have permission to do that!");
//				return true;
//			}
//
//			if (args.length == 1)
//			{
//				if (player.hasPermission("fairgod.unfair"))
//				{
//					toggleGod(player, false);
//					return true;
//				}
//
//				player.sendMessage(ChatColor.RED + "You don't have permission to do that!");
//				return true;
//			}
//
//			return false;
//		}
//		return false;
//	}
	
//	@EventHandler
	public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
		if ((event.getDamager() instanceof Player)) {
			if ((event.getEntity() instanceof Player)) {
				Player damager = (Player) event.getDamager();
				if (isGod(damager)) {
					if (isFair(damager)) {
						if (!damager.getWorld().getName().equals("GameWorld")) {
							if (damager.getGameMode() == GameMode.SURVIVAL) {
								event.setCancelled(true);
								toggleGod(damager, true);
							}
						} else {
							toggleGod(damager, true);
						}
					}
				}
			}
		}
	}

//	@EventHandler
	public void onEntityDamage(EntityDamageEvent event) {
		if ((event.getEntity() instanceof Player)) {
			Player player = (Player) event.getEntity();
			if (isGod(player)) {
				if (!player.getWorld().getName().equals("EventWorld")) {
					event.setCancelled(true);
				} else {
					toggleGod(player, true);
				}
			}
		}
	}

//	@EventHandler(priority = EventPriority.NORMAL)
	public void onShoot(EntityShootBowEvent event) {
		if ((event.getEntity() instanceof Player)) {
			Player archer = (Player) event.getEntity();
			if (isGod(archer)) {
				if (!archer.getWorld().getName().equals("EventWorld")) {
					if (archer.getGameMode() == GameMode.SURVIVAL) {
						event.setCancelled(true);
						toggleGod(archer, true);
					}
				} else {
					toggleGod(archer, true);
				}
			}
		}
	}
	
	public void log(String info) {
		plugin.getLogger().info("<FairGod> " + info);
	}
	
} public class ModAppWall {
	private CustomPlugin plugin;
	private Location p_nameSignLoc;
    private Location p_rateSignLoc;
	private Location u_nameSignLoc;
    private Location u_rateSignLoc;
	private Location d_nameSignLoc;
    private Location d_rateSignLoc;
	private int num;
	
	public ModAppWall(CustomPlugin plugin) {
		this.plugin = plugin;
	}
	
	@SuppressWarnings("deprecation")
	public void enable() {
			plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
				@Override  
				public void run() {
					updateWall();
				}
			}, 60, 20*60*10);
		log("Enabled");
	}
	
	public void updateWall() {
		
    	p_nameSignLoc = new Location(Bukkit.getWorld("Survival"), 68, 73, 161);
        p_rateSignLoc = new Location (Bukkit.getWorld("Survival"), 68, 73, 162);
    	u_nameSignLoc = new Location(Bukkit.getWorld("Survival"), 68, 73, 163);
        u_rateSignLoc = new Location (Bukkit.getWorld("Survival"), 68, 73, 164);
    	d_nameSignLoc = new Location(Bukkit.getWorld("Survival"), 68, 73, 165);
        d_rateSignLoc = new Location (Bukkit.getWorld("Survival"), 68, 73, 166);
        
		clearSigns();
		Connection con = null;
        Statement st = null;
        ResultSet rs = null;

        String url = "jdbc:mysql://192.185.24.94:3306/diamond_appstatus";
        String user = "diamond_admin";
        String password = "AdminControl123";
        
        Calendar cal = Calendar.getInstance();
        
        int month = cal.get(Calendar.MONTH);
        int day = cal.get(Calendar.DAY_OF_MONTH);
        int year = cal.get(Calendar.YEAR);
        day -= 10;
        if (day < 1) {
        	month--;
        	day = 30+day-10;
        }
        
        try {
            con = DriverManager.getConnection(url, user, password);
            st = con.createStatement();
//            st.execute("SELECT * FROM Pending");
            rs = st.executeQuery("SELECT * FROM Applications WHERE `Rating` >= 8.5 && `LastLogin` >= '" + year + "-" + month + "-" + day + "' ORDER BY `Applications`.`Timestamp` DESC;");
            num = 1;
            while (rs.next()) {
//            	pending.put(rs.getString(1), rs.getString(2));
            	addToPendingWall(rs.getString(1), rs.getString(2));
            }
            st = con.createStatement();
            rs = st.executeQuery("SELECT * FROM Applications WHERE `Rating` = 0.0 ORDER BY `Applications`.`Timestamp` DESC;");
            num = 1;
            while (rs.next()) {
            	addToUnreadWall(rs.getString(1), "NA");
            }
            st = con.createStatement();
            rs = st.executeQuery("SELECT * FROM Applications WHERE `Rating` < 8.5 ORDER BY `Applications`.`Timestamp` DESC;");
            num = 1;
            while (rs.next()) {
            	addToDeniedWall(rs.getString(1), rs.getString(2).replaceFirst("-", ChatColor.DARK_RED + ""));
            }

        } catch (SQLException ex) {
            log(ex.getMessage());
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (st != null) {
                    st.close();
                }
                if (con != null) {
                    con.close();
                }
            } catch (SQLException ex) {
                log(ex.getMessage());
            }
        }
	}
	
	public void addToPendingWall(String name, String rating) {
        if (p_nameSignLoc.getChunk() != null && p_rateSignLoc.getChunk() != null) {
        	Sign sign;
        	BlockState signBlock = Bukkit.getWorld("Survival").getBlockAt(p_nameSignLoc).getState();
        	BlockState rateBlock = Bukkit.getWorld("Survival").getBlockAt(p_rateSignLoc).getState();
        	int place = ((num - 1) % 4);
        	if (signBlock instanceof Sign) {
        		sign = (Sign) signBlock;
        		sign.setLine(place, name);
        		sign.update();
        	}
        	if (rateBlock instanceof Sign) {
        		sign = (Sign) rateBlock;
        		sign.setLine(place, ChatColor.DARK_BLUE + "Rating: " + rating);
        		sign.update();
        	}
        	if (num % 4 == 0) {
        		p_nameSignLoc.add(0, -1, 0);
        		p_rateSignLoc.add(0, -1, 0);
        	}
        	num++;
        }
	}

	public void addToUnreadWall(String name, String rating) {
		if (u_nameSignLoc.getChunk() != null && u_rateSignLoc.getChunk() != null) {
			Sign sign;
			BlockState signBlock = Bukkit.getWorld("Survival").getBlockAt(u_nameSignLoc).getState();
			BlockState rateBlock = Bukkit.getWorld("Survival").getBlockAt(u_rateSignLoc).getState();
			int place = ((num - 1) % 4);
			if (signBlock instanceof Sign) {
				sign = (Sign) signBlock;
				sign.setLine(place, name);
				sign.update();
			}
			if (rateBlock instanceof Sign) {
				sign = (Sign) rateBlock;
				sign.setLine(place, ChatColor.DARK_BLUE + "Rating: " + rating);
				sign.update();
			}
			if (num % 4 == 0) {
				u_nameSignLoc.add(0, -1, 0);
				u_rateSignLoc.add(0, -1, 0);
			}
			num++;
		}
	}
	
	public void addToDeniedWall(String name, String rating) {
		if (u_nameSignLoc.getChunk() != null && u_rateSignLoc.getChunk() != null) {
			Sign sign;
			BlockState signBlock = Bukkit.getWorld("Survival").getBlockAt(d_nameSignLoc).getState();
			BlockState rateBlock = Bukkit.getWorld("Survival").getBlockAt(d_rateSignLoc).getState();
			int place = ((num - 1) % 4);
			if (signBlock instanceof Sign) {
				sign = (Sign) signBlock;
				sign.setLine(place, name);
				sign.update();
			}
			if (rateBlock instanceof Sign) {
				sign = (Sign) rateBlock;
				sign.setLine(place, ChatColor.DARK_BLUE + "Rating: " + rating);
				sign.update();
			}
			if (num % 4 == 0) {
				d_nameSignLoc.add(0, -1, 0);
				d_rateSignLoc.add(0, -1, 0);
			}
			num++;
		}
	}
	
	public void clearSigns() {
		try {
			for (int x = 25; x <= 30; x++) {
				for (int y = 74; y >= 72; y--) {
					BlockState signState = p_nameSignLoc.getWorld().getBlockAt(x, y, 195).getState();
					if (signState instanceof Sign) {
						Sign sign = (Sign) signState;
						sign.setLine(0, "");
						sign.setLine(1, "");
						sign.setLine(2, "");
						sign.setLine(3, "");
						sign.update();
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void log(String info) {
		plugin.getLogger().info("<ModAppWall> " + info);
	}
} public class ModListWall {
	private CustomPlugin plugin;
	
	public ModListWall(CustomPlugin plugin) {
		this.plugin = plugin;
	}
	
	public void enable() {
		updateList(getModList());
		log("Enabled");
	}
	
	public ArrayList<String> getModList() {
		ArrayList<String> modList = new ArrayList<String>();
		Connection con = null;
		String url = "jdbc:mysql://localhost:3306/DiamondDom_Bungee";
		String user = "root";
		String password = "K2gEBBl6";
		try {
			con = DriverManager.getConnection(url, user, password);

			Statement st = (Statement) con.createStatement(); 
			ResultSet result = st.executeQuery("SELECT * FROM permissions_inheritance WHERE parent LIKE '%mod' && type = '1' && parent != 'HeadMod'");
			
			while (result.next()) {
				modList.add(result.getString("child"));	
			}
			
			con.close();
		} catch (SQLException e1) {
			e1.printStackTrace();
		}
		
		return modList;
	}
	
	public void updateList(ArrayList<String> list) {
		Sign a = null;
		Sign b = null;
		Sign c = null;
		Sign d = null;
		try {
			a = (Sign) Bukkit.getWorld("Survival").getBlockAt(60, 72, 172).getState();
			b = (Sign) Bukkit.getWorld("Survival").getBlockAt(60, 72, 171).getState();
			c = (Sign) Bukkit.getWorld("Survival").getBlockAt(60, 72, 170).getState();
			d = (Sign) Bukkit.getWorld("Survival").getBlockAt(60, 72, 169).getState();
			clearSign(a);
			clearSign(b);
			clearSign(c);
			clearSign(d);
		} catch (Exception e) {
			log("Failure to find signs.");
		}
		try {
			int i = 0;
			
			int spacing = 4;
			if (list.size() <= 16) {
				double s = list.size()/4;
				if (s > (int)s) {
					s++;
				}
				spacing = (int)s;
			}
			for (String name : list) {
				if (i < spacing) {
					a.setLine(i, ChatColor.AQUA + name);
				} else if (i < spacing*2) {
					b.setLine(i-spacing, ChatColor.AQUA + name);
				} else if (i < spacing*3) {
					c.setLine(i-spacing*2, ChatColor.AQUA + name);
				} else if (i < spacing*4) {
					d.setLine(i-spacing*3, ChatColor.AQUA + name);
				}
				i++;
			}
			a.update();
			b.update();
			c.update();
			d.update();
		} catch (Exception e) {
			log("Failure to write to signs.");
		}
	}
	
	public void clearSign(Sign sign) {
		sign.setLine(0, "");
		sign.setLine(1, "");
		sign.setLine(2, "");
		sign.setLine(3, "");
	}
	
	public void log(String info) {
		plugin.getLogger().info("<ModListWall> " + info);
	}
} public class SpawnMusic {
	
	private CustomPlugin plugin;

	public SpawnMusic(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
			@SuppressWarnings("deprecation")
			@Override
			public void run() {
				World w = Bukkit.getWorld("Survival");
				Jukebox a = (Jukebox) w.getBlockAt(64, 70, 198).getState();
				ArrayList<Material> discs = new ArrayList<Material>();
				discs.add(Material.getMaterial(2257));
				discs.add(Material.getMaterial(2258));
				discs.add(Material.getMaterial(2260));
				discs.add(Material.getMaterial(2261));
				discs.add(Material.getMaterial(2263));
				discs.add(Material.getMaterial(2264));
				discs.add(Material.getMaterial(2267));
				Block db = w.getBlockAt(a.getBlock().getLocation().clone().add(0,-1,0));
				int type = db.getData();
				type++;
				if (type > 6) {
					type = 0;
				}
				a.setPlaying(discs.get(type));
				db.setData((byte) type);
				//				
			}
		}, 20*5, 20*60*3);
		log("Enabled");
	}

	public void log(String info) {
		plugin.getLogger().info("<SpawnMusic> " + info);
	}
} public class StaffVotes {
	private CustomPlugin plugin;
	Inventory voteInv;
	ItemStack no;
	ItemStack yes;
	Chest chest;
	ArrayList<String> votingPlayers = new ArrayList<String>();

	public StaffVotes(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		noSlots.add(0);
		noSlots.add(9);
		noSlots.add(18);
		noSlots.add(1);
		noSlots.add(10);
		noSlots.add(19);
		noSlots.add(2);
		noSlots.add(11);
		noSlots.add(20);
		noSlots.add(3);
		noSlots.add(12);
		noSlots.add(21);
		yesSlots.add(8);
		yesSlots.add(17);
		yesSlots.add(26);
		yesSlots.add(7);
		yesSlots.add(16);
		yesSlots.add(25);
		yesSlots.add(5);
		yesSlots.add(15);
		yesSlots.add(24);
		yesSlots.add(4);
		yesSlots.add(14);
		yesSlots.add(23);
		log("Enabled");
	}
	
	public Inventory getChest() {
		chest = (Chest) Bukkit.getWorld("Survival").getBlockAt(59, 71, 171).getState();
		return chest.getBlockInventory();
	}
	
	public Inventory getInv() {
		Sign sign = (Sign) Bukkit.getWorld("Survival").getBlockAt(60, 71, 171).getState();
		Sign sign2 = (Sign) Bukkit.getWorld("Survival").getBlockAt(60, 71, 170).getState();
		
		String title = sign.getLine(1) + " " + sign.getLine(2) + " " + sign.getLine(3) + " " + sign2.getLine(1) + " " + sign2.getLine(2) + " " + sign2.getLine(3);
		String invtitle = title;
		if (title.length() > 32)
			invtitle = title.substring(0, 32);
		
		no = new ItemStack(Material.WOOL);
		no.setDurability((short) 14);
		ItemMeta im = no.getItemMeta();
		im.setDisplayName("Click to vote " + ChatColor.RED + "NO");
		List<String> list = new ArrayList<String>();
		list.add(title);
		im.setLore(list);
		no.setItemMeta(im);
		
		yes = new ItemStack(Material.WOOL);
		yes.setDurability((short) 5);
		im = yes.getItemMeta();
		im.setDisplayName("Click to vote " + ChatColor.GREEN + "YES");
		im.setLore(list);
		yes.setItemMeta(im);
		
		voteInv = Bukkit.getServer().createInventory(null, 9, invtitle);
		voteInv.setItem(0, no);
		voteInv.setItem(1, no);
		voteInv.setItem(2, no);
		voteInv.setItem(3, no);
		ItemStack ns = new ItemStack(Material.NETHER_STAR);
		im = ns.getItemMeta();
		im.setDisplayName("Pick One");
		ns.setItemMeta(im);
		voteInv.setItem(4, ns);
		voteInv.setItem(5, yes);
		voteInv.setItem(6, yes);
		voteInv.setItem(7, yes);
		voteInv.setItem(8, yes);
		return voteInv;
	}
	
	public void voteNo(Player player) {
		removePlayer(player);
		
		ItemStack head = new ItemStack(Material.SKULL_ITEM);
		head.setDurability((short)3);
		
		SkullMeta skull = (SkullMeta) head.getItemMeta();
		skull.setOwner(player.getName());
		head.setItemMeta(skull);
		
		ItemMeta im = head.getItemMeta();
		im.setDisplayName(ChatColor.DARK_RED + player.getName());
		ArrayList<String> lore = new ArrayList<String>();
		lore.add("Voting NO");
		im.setLore(lore);
		head.setItemMeta(im);
		
		getChest().setItem(getNextNoSlot(), head);
		player.openInventory(getChest());
	}

	public void voteYes(Player player) {
		removePlayer(player);
		
		ItemStack head = new ItemStack(Material.SKULL_ITEM);
		head.setDurability((short)3);
		
		SkullMeta skull = (SkullMeta) head.getItemMeta();
		skull.setOwner(player.getName());
		head.setItemMeta(skull);
		
		ItemMeta im = head.getItemMeta();
		im.setDisplayName(ChatColor.GREEN + player.getName());
		ArrayList<String> lore = new ArrayList<String>();
		lore.add("Voting YES");
		im.setLore(lore);
		head.setItemMeta(im);
		
		getChest().setItem(getNextYesSlot(), head);
		player.openInventory(getChest());
	}

	public void removePlayer(Player player) {
		for (ItemStack item : getChest().getContents()) {
			if (item != null && item.getType().equals(Material.SKULL_ITEM)) {
				SkullMeta skull = (SkullMeta) item.getItemMeta();
				if (skull.getOwner().equals(player.getName()))
					getChest().remove(item);
			}
		}
	}
	
	ArrayList<Integer> noSlots = new ArrayList<Integer>();
	ArrayList<Integer> yesSlots = new ArrayList<Integer>();
	
	public int getNextNoSlot() {
		for (int i : noSlots) {
			if (getChest().getItem(i) == null)
				return i;
		}
		return 0;
	}
	
	public int getNextYesSlot() {
		for (int i : yesSlots) {
			if (getChest().getItem(i) == null)
				return i;
		}
		return 0;
	}
	
	public boolean onCommand(CommandSender sender, String[] args) {
		if (!sender.hasPermission("customplugin.staffvote")) {
			sender.sendMessage(ChatColor.RED + "You don't have permission.");
			return true;
		}
		if (!(sender instanceof Player)) {
			sender.sendMessage("You must be a player to vote");
			return true;
		}
		Player player = (Player) sender;
		if (args.length > 0) {
			if (!sender.hasPermission("customplugin.staffvote.manage")) {
				sender.sendMessage(ChatColor.RED + "Only headadmin and up can manage staffvotes.");
				return true;
			}
			String arg = args[0];
//			if (arg.equals("setquestion")) {
//				String question = "";
//				for (String str: args) {
//					if (!str.equals("setquestion")) {
//						question += str + " ";
//					}
//				}
//				question = question.substring(0, question.length() - 1);
//				Sign sign = (Sign) Bukkit.getWorld("Survival").getBlockAt(64, 71, 133).getState();
//				if (question.length() > 16) {
//					String line1 = question.substring(question.substring(0, 16).lastIndexOf(" "));
//					question = question.substring(line1.length(), question.length());
//					if (question.length() > 16) {
//						String line2 = question.substring(question.substring(0, 16).lastIndexOf(" "));
//						question = question.substring(line2.length(), question.length());
//						if (question.length() > 16) {
//							String line3 = question.substring(question.substring(0, 16).lastIndexOf(" "));
//							question = question.substring(line3.length(), question.length());
//						} else {
//							sign.setLine(1, line1);
//							sign.setLine(2, line2);
//							sign.setLine(3, question);
//						}
//					} else {
//						sign.setLine(1, line1);
//						sign.setLine(2, question);
//						sign.setLine(3, "");
//					}
//				} else {
//					sign.setLine(1, question);
//					sign.setLine(2, "");
//					sign.setLine(3, "");
//				}
//				sign.update();
//				sender.sendMessage(ChatColor.GREEN + "Question changed to: " + ChatColor.BLUE + sign.getLine(1) + " " + sign.getLine(2) + " " + sign.getLine(3));
//				return true;
//			} else 
			if (arg.equalsIgnoreCase("clear")) {
				getChest().clear();
				sender.sendMessage(ChatColor.GREEN + "Vote chest cleared.");
				return true;
			} else if (arg.equalsIgnoreCase("open")) {
				player.openInventory(getChest());
			} else {
				sender.sendMessage(ChatColor.RED + "Error: Args can be open, or clear");
				return true;
			}
		}
		votingPlayers.add(player.getName());
		player.openInventory(getInv());
		return true;
	}
	
	public void onInventoryClick(InventoryClickEvent event) {
		HumanEntity hm = event.getWhoClicked();
		ItemStack ci = event.getCurrentItem();
		if (votingPlayers.contains(hm.getName())) {
			event.setCancelled(true);
			if (event.getCurrentItem() != null) {
				if (event.getCurrentItem().getDurability() == (short) 14)
					voteNo((Player) hm);
				if (event.getCurrentItem().getDurability() == (short) 5)
					voteYes((Player) hm);
				
				votingPlayers.remove(event.getWhoClicked().getName());
			}
		}
		if (ci != null && ci.getType().equals(Material.SKULL_ITEM)) {
			ItemMeta skull = event.getCurrentItem().getItemMeta();
			List<String> lore = skull.getLore();
			if (lore != null && lore.size() > 0) {
				if (lore.get(0).startsWith("Voting ")) {
					event.setCancelled(true);
				}
			}
		}
	}
	
	public void onInventoryClose(InventoryCloseEvent event) {
		if (votingPlayers.contains(event.getPlayer().getName())) {
			votingPlayers.remove(event.getPlayer().getName());
		}
	}
	
	public void onPlayerJoinEvent(PlayerJoinEvent event) {
		if (event.getPlayer().hasPermission("customplugin.staffvote")) {
			for (ItemStack item : getChest().getContents()) {
				if (item != null && item.getType().equals(Material.SKULL_ITEM)) {
					SkullMeta skull = (SkullMeta) item.getItemMeta();
					if (skull.getOwner().equals(event.getPlayer().getName()))
						return;
				}
			}
			event.getPlayer().sendMessage(ChatColor.BLUE + "STAFFVOTE: " + ChatColor.RED + "You have yet to vote!");
			Sign sign = (Sign) Bukkit.getWorld("Survival").getBlockAt(60, 71, 171).getState();
			Sign sign2 = (Sign) Bukkit.getWorld("Survival").getBlockAt(60, 71, 170).getState();
			
			String title = sign.getLine(1) + " " + sign.getLine(2) + " " + sign.getLine(3) + " " + sign2.getLine(1) + " " + sign2.getLine(2) + " " + sign2.getLine(3);
			event.getPlayer().sendMessage(ChatColor.GREEN + title);
		}
	}

	public void log(String info) {
		plugin.getLogger().info("<StaffVotes> " + info);
	}
} public class TopPvPers {
	
	private CustomPlugin plugin;
	
	public TopPvPers(CustomPlugin plugin) {
		this.plugin = plugin;
	}
	
	private ArrayList<String> records = readFile();
	private boolean processing = false;
	
	public void enable() {
		Calendar c = Calendar.getInstance();
		int day = c.get(Calendar.DAY_OF_WEEK);
		log ("Day: " + day);
		if (day == 2 && highestKill(300)) {
			log("Clearing all KDR's shortly");
			plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
				@Override 
				public void run() {
					Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "pvp reset kdr all");
				}
			}, 200);
		}
//		updateSigns();
//		plugin.getServer().getPluginManager().registerEvents(this, plugin);
		log("Enabled");
	}
	
	public boolean highestKill(int max) {
		for (String line : records) {
			String[] splitLine = line.split(";");
			if (Integer.parseInt(splitLine[1]) > max) {
				return true;
			}
		}
		return false;
	}
	
	public ArrayList<String> readFile() {
		ArrayList<String> lines = new ArrayList<String>();
		try{
			Scanner reader = new Scanner(new File("plugins/PvPReward/pvpreward.records"));
			while(reader.hasNextLine()){;
			String currentLine = reader.nextLine();
			lines.add(currentLine);
			}
		}catch(FileNotFoundException e){
			log("Could not load PvPReward Records!");
		}
		return lines;
	}
	
	public void setIndividualStats(String player, Sign sign) {
		records = readFile();
		sign.setLine(0, Bukkit.getPlayer(player).getPlayerListName());
		double kdr = 0;
		String[] splitLine = {player,"0","0","0"};
		for (String line : records) {
			splitLine = line.split(";");
			if (splitLine[0].equals(player)) {
				if (Integer.parseInt(splitLine[2]) != 0) {
					kdr = (double)Integer.parseInt(splitLine[1]) / Integer.parseInt(splitLine[2]);
				} else {
					kdr = Integer.parseInt(splitLine[1]);
				}
				break;
			}
		}
		sign.setLine(1, ChatColor.DARK_RED + "KDR: " + ChatColor.DARK_BLUE + kdr + "          ");
		sign.setLine(2, ChatColor.DARK_RED + "Kills: " + ChatColor.DARK_BLUE + splitLine[1] + "         ");
		sign.setLine(3, ChatColor.DARK_RED + "Deaths: " + ChatColor.DARK_BLUE + splitLine[2] + "         ");
		sign.update();
	}
	
	@SuppressWarnings("null")
	public void updateSigns() {
		records = readFile();
		processing = true;
		@SuppressWarnings({ "unchecked", "rawtypes" })
		Map<String, Double> data = new HashMap();
		ValueComparator bvc =  new ValueComparator(data);
		TreeMap<String,Double> tops = new TreeMap<String,Double>(bvc);
		for (String line : records) {
			String[] splitLine = line.split(";");
			double kdr;
			if (Integer.parseInt(splitLine[2]) != 0) {
				kdr = (double)Integer.parseInt(splitLine[1]) / Integer.parseInt(splitLine[2]);
			} else {
				kdr = Integer.parseInt(splitLine[1]);
			}
			data.put(splitLine[0], kdr);
		}
		tops.putAll(data);
		
	    @SuppressWarnings("rawtypes")
		Iterator it = tops.entrySet().iterator();
	    
	    @SuppressWarnings({ "unchecked", "rawtypes" })
		ArrayList<String> write = new ArrayList(0);
	    
	    int playerNum = 1;
	    
	    while (it.hasNext()) {
	        @SuppressWarnings("rawtypes")
			Map.Entry pairs = (Map.Entry)it.next();
	        String nameLine = playerNum + ". " + pairs.getKey();
	        if (nameLine.length() > 14)
	        	nameLine = nameLine.substring(0, 14);
	        nameLine += ":";
	        if (write == null) {
	        	write.set(0, nameLine);
	        } else {
	        	write.add(nameLine);
	        }
	        write.add(ChatColor.DARK_RED + "KDR: " + pairs.getValue());
	        playerNum++;
	        it.remove();
	    }

	    Sign sign;
	    try {
	    	sign = (Sign) new Location(Bukkit.getWorld("Survival"), 272, 65, 321).getBlock().getState();
	    	sign.setLine(0, write.get(0));
	    	sign.setLine(1, write.get(1));
	    	sign.setLine(2, write.get(2));
	    	sign.setLine(3, write.get(3));
	    	sign.update();
	    	sign = (Sign) new Location(Bukkit.getWorld("Survival"), 272, 65, 322).getBlock().getState();
	    	sign.setLine(0, write.get(4));
	    	sign.setLine(1, write.get(5));
	    	sign.setLine(2, write.get(6));
	    	sign.setLine(3, write.get(7));
	    	sign.update();
	    	sign = (Sign) new Location(Bukkit.getWorld("Survival"), 272, 65, 323).getBlock().getState();
	    	sign.setLine(0, write.get(8));
	    	sign.setLine(1, write.get(9));
	    	sign.setLine(2, write.get(10));
	    	sign.setLine(3, write.get(11));
	    	sign.update();
	    	sign = (Sign) new Location(Bukkit.getWorld("Survival"), 272, 65, 324).getBlock().getState();
	    	sign.setLine(0, write.get(12));
	    	sign.setLine(1, write.get(13));
	    	sign.setLine(2, write.get(14));
	    	sign.setLine(3, write.get(15));
	    	sign.update();
	    	sign = (Sign) new Location(Bukkit.getWorld("Survival"), 272, 65, 325).getBlock().getState();
	    	sign.setLine(0, write.get(16));
	    	sign.setLine(1, write.get(17));
	    	sign.setLine(2, write.get(18));
	    	sign.setLine(3, write.get(19));
	    	sign.update();
	    	sign = (Sign) new Location(Bukkit.getWorld("Survival"), 272, 65, 326).getBlock().getState();
	    	sign.setLine(0, write.get(20));
	    	sign.setLine(1, write.get(21));
	    	sign.setLine(2, write.get(22));
	    	sign.setLine(3, write.get(23));
	    	sign.update();
	    } catch (Exception e) {
	    	log("Failed to write signs on left side!");
	    }
	    try {
	    	sign = (Sign) new Location(Bukkit.getWorld("Survival"), 246, 65, 326).getBlock().getState();
	    	sign.setLine(0, write.get(0));
	    	sign.setLine(1, write.get(1));
	    	sign.setLine(2, write.get(2));
	    	sign.setLine(3, write.get(3));
	    	sign.update();
	    	sign = (Sign) new Location(Bukkit.getWorld("Survival"), 246, 65, 325).getBlock().getState();
	    	sign.setLine(0, write.get(4));
	    	sign.setLine(1, write.get(5));
	    	sign.setLine(2, write.get(6));
	    	sign.setLine(3, write.get(7));
	    	sign.update();
	    	sign = (Sign) new Location(Bukkit.getWorld("Survival"), 246, 65, 324).getBlock().getState();
	    	sign.setLine(0, write.get(8));
	    	sign.setLine(1, write.get(9));
	    	sign.setLine(2, write.get(10));
	    	sign.setLine(3, write.get(11));
	    	sign.update();
	    	sign = (Sign) new Location(Bukkit.getWorld("Survival"), 246, 65, 323).getBlock().getState();
	    	sign.setLine(0, write.get(12));
	    	sign.setLine(1, write.get(13));
	    	sign.setLine(2, write.get(14));
	    	sign.setLine(3, write.get(15));
	    	sign.update();
	    	sign = (Sign) new Location(Bukkit.getWorld("Survival"), 246, 65, 322).getBlock().getState();
	    	sign.setLine(0, write.get(16));
	    	sign.setLine(1, write.get(17));
	    	sign.setLine(2, write.get(18));
	    	sign.setLine(3, write.get(19));
	    	sign.update();
	    	sign = (Sign) new Location(Bukkit.getWorld("Survival"), 246, 65, 321).getBlock().getState();
	    	sign.setLine(0, write.get(20));
	    	sign.setLine(1, write.get(21));
	    	sign.setLine(2, write.get(22));
	    	sign.setLine(3, write.get(23));
	    	sign.update();
	    } catch (Exception e) {
	    	log("Failed to write signs on right side!");
	    }
	    Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
	    	public void run() {
	    		processing = false;
	    	}
	    }, 100L);
	}
	
	public boolean alreadyHasASign(Player player) {
		ArrayList<String> topLines = new ArrayList<String>();
		
		try {
		Sign sign = (Sign) new Location(Bukkit.getWorld("Survival"), 272, 65, 321).getBlock().getState();
		topLines.add(sign.getLine(0));
		sign = (Sign) new Location(Bukkit.getWorld("Survival"), 272, 65, 322).getBlock().getState();
		topLines.add(sign.getLine(0));
		sign = (Sign) new Location(Bukkit.getWorld("Survival"), 272, 65, 323).getBlock().getState();
		topLines.add(sign.getLine(0));
		sign = (Sign) new Location(Bukkit.getWorld("Survival"), 272, 65, 324).getBlock().getState();
		topLines.add(sign.getLine(0));
		sign = (Sign) new Location(Bukkit.getWorld("Survival"), 272, 65, 325).getBlock().getState();
		topLines.add(sign.getLine(0));
		sign = (Sign) new Location(Bukkit.getWorld("Survival"), 272, 65, 326).getBlock().getState();
		topLines.add(sign.getLine(0));
		
		sign = (Sign) new Location(Bukkit.getWorld("Survival"), 246, 65, 326).getBlock().getState();
		topLines.add(sign.getLine(0));
		sign = (Sign) new Location(Bukkit.getWorld("Survival"), 246, 65, 325).getBlock().getState();
		topLines.add(sign.getLine(0));
		sign = (Sign) new Location(Bukkit.getWorld("Survival"), 246, 65, 324).getBlock().getState();
		topLines.add(sign.getLine(0));
		sign = (Sign) new Location(Bukkit.getWorld("Survival"), 246, 65, 323).getBlock().getState();
		topLines.add(sign.getLine(0));
		sign = (Sign) new Location(Bukkit.getWorld("Survival"), 246, 65, 322).getBlock().getState();
		topLines.add(sign.getLine(0));
		sign = (Sign) new Location(Bukkit.getWorld("Survival"), 246, 65, 321).getBlock().getState();
		topLines.add(sign.getLine(0));
		} catch (Exception e) {}
		
		boolean already = topLines.contains(player.getPlayerListName());
		if (already) {
			player.sendMessage(ChatColor.GOLD + "[" + ChatColor.GREEN + "LeaderBoard" + ChatColor.GOLD + "]" + ChatColor.RED + " You have your own sign!");
		}
		return already;
	}
	
//	@EventHandler
	public void onPlayerInteractEvent(PlayerInteractEvent event) {
		Block clicked = event.getClickedBlock();
		if (clicked != null && clicked.getState() instanceof Sign) {
			Location loc = clicked.getLocation();
			if (loc.getBlockX() == 246 || loc.getBlockX() == 272) {
				if (loc.getBlockY() == 66) {
					if (loc.getBlockZ() == 322 || loc.getBlockZ() == 325) {
						if (!processing) {
							updateSigns();
							log(event.getPlayer().getName() + " reset sign data");
						}
					}
				} else if (loc.getBlockY() == 65) {
					if (loc.getBlockZ() >= 321 && loc.getBlockZ() <= 326) {
						if(!alreadyHasASign(event.getPlayer()))
							setIndividualStats(event.getPlayer().getName(), (Sign) clicked.getState());
					}
				}
			} 
		}
	}
	
//	@EventHandler
	public void onPlayerDeathEvent(EntityDeathEvent event) {
		if (event.getEntity() instanceof Player) {
			Player player = (Player) event.getEntity();
			Player killer = player.getKiller();
			String world = player.getWorld().getName();
			if (killer != null && killer instanceof Player && !(world.equals("Build") || world.equals("Destruction"))) {
				if (!PvPReward.hasPermisson(killer, player) || world.equals("GameWorld")) {
					PvPReward.getRecord(player.getName()).incrementDeaths();
					PvPReward.getRecord(killer.getName()).incrementKills();
				}
			}
		}
	}
	
	public void log(String info) {
		plugin.getLogger().info("<TopPvPers> " + info);
	}
} public class VoteReceiver implements Listener {
	private CustomPlugin plugin;

	public VoteReceiver(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		plugin.getServer().getPluginManager().registerEvents(this, plugin);
		log("Enabled");
	}
	
	@EventHandler
	public void voteMade(VotifierEvent event) {
//		event.getVote().setUsername("Esaych");
		String username = event.getVote().getUsername();

		String foundUser = VoteSQL.userExists(username);
		if (foundUser.equals("")) {
			Votifier.getInstance().getServer().broadcastMessage(ChatColor.translateAlternateColorCodes("&".charAt(0), "&6[&bDD&2Votes&6] &aA &4nonexistent&a player named '%name' voted for the server!".replaceAll("%name", username)));
			return;
		}
		Votifier.getInstance().getServer().broadcastMessage(ChatColor.translateAlternateColorCodes("&".charAt(0), "&6[&bDD&2Votes&6] &a%name voted for the server!".replaceAll("%name", foundUser)));
		com.vexsoftware.votifier.model.Vote inVote = event.getVote();
		new Vote(foundUser, (int) (System.currentTimeMillis()/1000), inVote.getServiceName(), 0, false);
		plugin.voteRewards.msg(foundUser, "Your vote from " + inVote.getServiceName() + " has been added! &e&lThank you!");

//		if (VoteSQL.getVotesLast24(foundUser) == 1)
//			BungeeGlobalCommand.sendCommand("broadcast " + foundUser + " just voted for today! Did you?");
		
		ArrayList<Vote> votes = VoteSQL.filterVotes(foundUser, (int) (System.currentTimeMillis()/1000 - 60*60*24), null, false, true);
		
		if (votes.size() == 3) {
			DonationCredit.addCredits(foundUser, 1);
			for (Vote dailyVote : votes) {
				dailyVote.donationcreditVote(true);
			}
			plugin.voteRewards.msg(foundUser, "You have been awarded 1 ($0.25) donation credits for voting 3 times today.");
		}
	}

	public void log(String info) {
		plugin.getLogger().info("<VoteReceiver> " + info);
	}
} public class WarpWild {
	private CustomPlugin plugin;

	public WarpWild(CustomPlugin plugin) {
		this.plugin = plugin;
	}
	public ArrayList<Player> warpedWild = new ArrayList<Player>();

	public void enable() {
		log("Enabled");
	}
	
	@EventHandler(priority=EventPriority.HIGHEST)
	public void onCommandPreprocess(PlayerCommandPreprocessEvent event)
	{	
		Player player = event.getPlayer();
		if (event.getMessage().equalsIgnoreCase("/warp wild")) {
			if (!warpedWild.contains(player)) {
				int min = -10000, max = 10000;
				int x = min + (int)(Math.random() * ((max - min) + 1));
				int z = min + (int)(Math.random() * ((max - min) + 1));
				int y;
				Location loc = new Location(player.getWorld(), x, 60, z);
				for (y = 60; y < 200; y++) {
					loc = new Location(player.getWorld(), x, y, z);
					if (player.getWorld().getBlockAt(loc).getType() == Material.WATER || player.getWorld().getBlockAt(loc).getType() == Material.STATIONARY_WATER) {
						x = min + (int)(Math.random() * ((max - min) + 1));
						z = min + (int)(Math.random() * ((max - min) + 1));
						y = 60;
					}
					if (player.getWorld().getBlockAt(loc).getType() == Material.AIR)
						break;
				}
				player.teleport(loc.clone().add(0.5, 0, 0.5));
				player.sendMessage(ChatColor.GOLD + "Warping to " + ChatColor.RED + "Wild" + ChatColor.GOLD + ". " + ChatColor.DARK_RED + "Caution: " + ChatColor.RED + "Might take some time to load.");
				warpedWild.add(player);
			} else {
				player.sendMessage(ChatColor.RED + "Error: " + ChatColor.DARK_RED + "You may only use warp wild once.");
			}
			event.setCancelled(true);
		}
	}

	public void log(String info) {
		plugin.getLogger().info("<WarpWild> " + info);
	}
} public class WelcomeBook {
	private CustomPlugin plugin;

	public WelcomeBook(CustomPlugin plugin) {
		this.plugin = plugin;
	}
	
	ItemStack book = new ItemStack(Material.WRITTEN_BOOK);
	
	public void enable() {
		writeBook();
		log("Enabled");
	}
	
	public void writeBook() {
		BookMeta bm = (BookMeta)book.getItemMeta();
		bm.setAuthor("DD Staff");
		bm.setTitle("Diamond Dominion Server Guide");
		ArrayList<String> pages = new ArrayList<String>();
		pages.add(ChatColor.translateAlternateColorCodes('&', 
				"Welcome to the\n&1&oDiamond Dominion!\n\n" + 
				"&0Our rules can be seen by typing &2/rules\n" +
				"&0All issues should be brought up to &cAdmins&0, &aModerators&0, or &6VIMods\n\n" +
				"&0You can always return to spawn with &2/spawn"
			));
		pages.add(ChatColor.translateAlternateColorCodes('&',
				"&1&lOur chat format:\n\n" +
				"&bFaction\n&3<World&a(Channel)&3>\n&e<&6Donor Prefix&e>\n&cRankColor&0+&8Name:\n&0Message\n\n" +
				"&0Message players:\n&2/msg [player] [msg]\n" + 
				"&0Reply to messages:\n&2/r [msg]"
			));
		pages.add(ChatColor.translateAlternateColorCodes('&',
				"&1&lUseful warps:\n\n" + 
				"&2/warp &1shop\n" +
				"&2/warp &1info\n" + 
				"&2/warp &1rules\n" +
				"&2/warp &1modapps\n" +
				"&2/warp &1portals\n" +
				"&2/warp &1contest\n" +
				"&2/warp &3<World>\n\n" +
				"&0Replace &3<World> &0with the name/abbreviation of the server worlds in next pages."
				));
		pages.add(ChatColor.translateAlternateColorCodes('&',
				"&3<SV> &4&lSurvival&r&0:\n" + 
				"Our Grief World. Claim and protect land using Factions, type /f help for faction help. Raiding, and tnt usage all allowed.\n\n" +
				"&3<N> &4&lNether&r&0\n" +
				"&3<E> &6&lEnd&r&0\n" +
				"Typical Nether and End linked to Survival."
				));
		pages.add(ChatColor.translateAlternateColorCodes('&', 
				"&3<GF> &1&lTownyWorld&r&0:\n" +
				"Griefing and Raiding is NOT allowed. PvP disabled, peaceful living. Use /towny for help.\n\n" +
				"&3<SB> &2&lSkyBlock&e&0:\n" +
				"SkyBlock world! Survive on floating islands. Build up your island rank."
				));
		pages.add(ChatColor.translateAlternateColorCodes('&',
				"&3<B> &6&lBuild&r&0:\n" + 
				"Creative plot world. Claiming help provided. Griefing not allowed. Specialty extensions for all designers.\n\n" +
				"Build world extensions:\n" + 
				"&3<RS> &4&lRedstone&r&0\n" +
				"&3<PX> &1&lPixelArt&r&0\n" +
				"&3<RS> &2&lFreeBuild&r&0\n\n" +
				"&3<DS> &4&l&oDestruction&4&0"
				));
		pages.add(ChatColor.translateAlternateColorCodes('&',
				"&3<EW> &1&lEventWorld&r&0:\n" +
				"Many games including MobArena, WalkInPvP, Hockey, Spleef, CTF, Trampoline, PaintBall, Parkour.\n\n" +
				"&3<SG> &4&lSurvivalGames&r&0:\n" +
				"Join games and fight to the death with others in the famous Survival Games, with great maps."
				));
		pages.add(ChatColor.translateAlternateColorCodes('&',
				"&1&lUseful tips:&r&0\n" +
				" Playing for 24 hours will give you &bRespected\n" +
				"&0 Voting 60 times a month with &2/vote&0 can buy you a donor rank\n" + 
				" Spawn and creative worlds provide beast sprint. &2/sprint&0 toggles\n" +
				" Smelting &4rotten flesh &0gives you leather\n"
				));
		pages.add(ChatColor.translateAlternateColorCodes('&',
				" Mob spawners change mob like noteblocks change note" +
				" Plots in creative world link when claimed together\n" +
				" We have a secret potion shop\n" +
				" Build launch pads like the ones at warzone anywhere.\n" + 
				" &4R&6a&2i&1n&5b&4o&6w &0armor is only for $20+ donors\n"
				));
		bm.setPages(pages);
		book.setItemMeta(bm);
	}
	
	public void onKitStarterGiven(Player player) {
		File File = new File("plugins/Essentials/userdata/" + player.getName().toLowerCase() + ".yml");
		FileConfiguration YMLFile = YamlConfiguration.loadConfiguration(File);
		if (YMLFile.getString("starterbook") == null) {
			player.getInventory().addItem(book);
			YMLFile.set("starterbook", true);
			try {
				YMLFile.save(File);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void onCommandPreprocess(PlayerCommandPreprocessEvent event)
	{
		if ((event.getMessage().toLowerCase().startsWith("/kit starter"))) {
			onKitStarterGiven(event.getPlayer());
		}
	}
	
	public void log(String info) {
		plugin.getLogger().info("<WelcomeBook> " + info);
	}
} public class WelcomeSign {
	private CustomPlugin plugin;

	public WelcomeSign(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	private int scroll = 0;
	public Sign sign;

	public void enable() {
		sign = (Sign) Bukkit.getWorld("Survival").getBlockAt(64, 72, 200).getState();
		Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
			@Override
			public void run() {
				sign.setLine(2, ChatColor.AQUA + ("Diamond Dominion     Diamond Dominion").substring(scroll, scroll + 15));
				sign.update();
				scroll++;
				if (scroll > 20)
					scroll = 0;
			}
		}, 20*5, 5);
		log("Enabled");
	}

	public void log(String info) {
		plugin.getLogger().info("<WelcomeSign> " + info);
	}
} public class AutoConfiscate implements Listener {
	private CustomPlugin plugin;
	private FileConfiguration chestData = null;
	private File chestDataFile = null;
	
	public AutoConfiscate(CustomPlugin plugin) {
		this.plugin = plugin;
	}
	
	public void enable() {
		plugin.getServer().getPluginManager().registerEvents(this, plugin);
		reloadChestData();
		try {
			if (getChestData().getString("first_chest.location.world").equals("")) {
				log("Reloading Chest Data Defaults");
				getChestData().set("first_chest.location.world", "Survival");
				getChestData().set("first_chest.location.x", 196);
				getChestData().set("first_chest.location.y", 64);
				getChestData().set("first_chest.location.z", 177);
				getChestData().set("players_confiscated", 0);
				getChestData().set("chest_range", 0);
			}
		} catch (Exception e) {
			log("Reloading Chest Data Defaults");
			getChestData().set("first_chest.location.world", "Survival");
			getChestData().set("first_chest.location.x", 196);
			getChestData().set("first_chest.location.y", 64);
			getChestData().set("first_chest.location.z", 177);
			getChestData().set("players_confiscated", 0);
			getChestData().set("chest_range", 0);
		}
//		if (node.equals("")) {
//			log("Reloading Chest Data Defaults");
//			getChestData().set("first_chest.location.world", "Survival");
//			getChestData().set("first_chest.location.x", 196);
//			getChestData().set("first_chest.location.y", 64);
//			getChestData().set("first_chest.location.z", 200);
//			getChestData().set("players_confiscated", 0);
//			getChestData().set("chest_range", 0);
//		}
		saveChestData();
		log("Enabled");
	}
	
	public boolean onCommand(CommandSender sender, String[] args) {
		if (args.length == 0) {
			msg(sender, "Invalid Arguments!");
			return true;
		}
		if (args[0].equalsIgnoreCase("tpchest")) {
			if (sender instanceof Player) {
				Player player = (Player) sender;
				if (((Player) sender).hasPermission("autoconfiscate.admin")) {
					if (args.length >= 2) {
						if (playerExists(args[1])) {
							World world = Bukkit.getWorld(getChestData().getString("first_chest_location.world"));
							int x = getChestData().getInt(args[1] + ".chest_location.x");
							String isY = getChestData().getString(args[1] + ".chest_location.y");
							if (isY == null) {
								getChestData().set(args[1] + ".chest_location.y", getChestData().getInt("first_chest_location.y"));
								saveChestData();
							}
							int y = getChestData().getInt(args[1] + ".chest_location.y");
							int z = getChestData().getInt(args[1] + ".chest_location.z");
							Location chestLoc = new Location(world, x + 0.5, y, z + 1.5);
							player.teleport(chestLoc);
							msg(sender, "Teleported to " + args[1] + "'s chest");
						} else {
							msg(sender, "Player not found");
						}
					} else {
						msg(sender, "Correct use: /ac tpchest <player>");
					}
				} else {
					msg(sender, "You have no permission to do that!");
				}
			} else {
				msg(sender, "You can't tp to a chest!");
			}
		} else if (args[0].equalsIgnoreCase("regen")) {
			if (sender instanceof Player) {
				if (((Player) sender).hasPermission("autoconfiscate.admin")) {
					regen();
					msg(sender, "Area Regenerated.");
				}
			} else {
				regen();
				msg(sender, "Area Regenerated.");
			}
		} else {
			msg(sender, "Invalid Command");
		}
		return true;
	}
	
	@SuppressWarnings("deprecation")
	public void regen() {
		try {
			Scanner scanner = new Scanner(chestDataFile);
			ArrayList<String> lines = new ArrayList<String>();
			while (scanner.hasNext()) {
				String string = scanner.nextLine();
				if (!string.startsWith(" ")) {
					if (!(string.startsWith("enabled: ") || string.equals("first_chest_location:") || string.startsWith("players_confiscated:") || string.startsWith("chest_range:")))
						lines.add(string.substring(0, string.length()-1));
				}
			}
			for (String name : lines) {
				String isY = getChestData().getString(name + ".chest_location.y");
				if (isY == null) {
					getChestData().set(name + ".chest_location.y", getChestData().getInt("first_chest.location.y"));
				}
				int x = getChestData().getInt(name + ".chest_location.x");
				int y = getChestData().getInt(name + ".chest_location.y");
				int z = getChestData().getInt("first_chest.location.z");
				y++;
				
				blockSet(x, y, z-1, 4);
				blockSet(x+1, y, z-1, 4);
				
				blockSet(x, y, z, 68);
				
				Sign sign = (Sign) new Location(Bukkit.getWorld(getChestData().getString("first_chest.location.world")), x, y, z).getBlock().getState();
				sign.setRawData((byte)3);
				sign.update();
				
				sign.setLine(0, ChatColor.WHITE + "-=-=-=-=-=-=-");
				sign.setLine(1, ChatColor.DARK_RED + "CONFISCATED:");
				sign.setLine(2, name);
				sign.setLine(3, ChatColor.WHITE + "-=-=-=-=-=-=-");
				sign.update();

				blockSet(x+1, y, z, 50);
//				log(name + ", " + x + ";" + y + ";" + z);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	public void msg(CommandSender sender, String msg) {
		if (sender instanceof Player) {
			Player player = (Player) sender;
			player.sendMessage(ChatColor.DARK_GREEN + "[" + ChatColor.GOLD + "AutoConfiscate" + ChatColor.DARK_GREEN + "] " + ChatColor.WHITE + msg);
		} else {
			log(msg);
		}
	}
	
	@SuppressWarnings("deprecation")
	public void scanInventory(Player player, Inventory inv) {
		reloadChestData();
		if (!(player.getGameMode() == GameMode.CREATIVE)
				&& !player.getWorld().getName().equals("GameWorld")
				&& !player.hasPermission("autoconfiscate.bypass")) {
			
			scanPlayerArmor(player);
			
			int diamonds = 0;
			int emeralds = 0;
			int dragonEggs = 0;
			int superGoldenApples = 0;

			for (int i = 0; i < inv.getSize(); i++) {
				ItemStack is = inv.getItem(i);
				if (is != null) {
//					ItemStack isOld = is;
//					is = replaceItem(is);
//					if (isOld != is) {
//						inv.remove(isOld);
//						inv.addItem(is);
//					}
					
					if (confiscatable(player, is)) {
						inv.remove(is);
//						if (plugin.getConfig().getBoolean("confiscate.supply_with_unenchanted_item") && !itemType(is).equals("other") && is.getEnchantments().size() != 0) {
//							ItemStack noEnchants = new ItemStack(is.getType(), is.getAmount(), is.getDurability());
//							inv.addItem(noEnchants);
//						}
//						if (plugin.getConfig().getBoolean("chest_room.create")) {
							moveToChest(player, is);
							saveChestData();
//						}
						addToList(player, is);
					}
					if (is.getTypeId() == 57)
						diamonds += is.getAmount();
					if (is.getTypeId() == 133)
						emeralds += is.getAmount();
					if (is.getTypeId() == 122)
						dragonEggs += is.getAmount();
					if (is.getTypeId() == 322 && is.getDurability() == (short) 1)
						superGoldenApples += is.getAmount();
				}
			}

			int maxDiamonds = 320;
			int maxEmeralds = 320;
			int maxDragonEggs = 5;
			int maxSuperGoldenApples = 192;
			
			if (diamonds > maxDiamonds) {
				inv.remove(Material.DIAMOND_BLOCK);
				ItemStack newItems = new ItemStack(Material.DIAMOND_BLOCK, maxDiamonds);
				ItemStack moveItems = new ItemStack(Material.DIAMOND_BLOCK, diamonds-maxDiamonds);
				inv.addItem(newItems);
				moveToChest(player, moveItems);
				saveChestData();
			}
			if (emeralds > maxEmeralds) {
				inv.remove(Material.EMERALD_BLOCK);
				ItemStack newItems = new ItemStack(Material.EMERALD_BLOCK, maxEmeralds);
				ItemStack moveItems = new ItemStack(Material.EMERALD_BLOCK, emeralds-maxEmeralds);
				inv.addItem(newItems);
				moveToChest(player, moveItems);
				saveChestData();
			}
			if (dragonEggs > maxDragonEggs) {
				inv.remove(Material.DRAGON_EGG);
				ItemStack newItems = new ItemStack(Material.DRAGON_EGG, maxDragonEggs);
				ItemStack moveItems = new ItemStack(Material.DRAGON_EGG, dragonEggs-maxDragonEggs);
				inv.addItem(newItems);
				moveToChest(player, moveItems);
				saveChestData();
			}
			if (superGoldenApples > maxSuperGoldenApples) {
				inv.remove(Material.GOLDEN_APPLE);
				ItemStack newItems = new ItemStack(Material.GOLDEN_APPLE, maxSuperGoldenApples);
				newItems.setDurability((short)1);
				ItemStack moveItems = new ItemStack(Material.GOLDEN_APPLE, superGoldenApples-maxSuperGoldenApples);
				moveItems.setDurability((short)1);
				inv.addItem(newItems);
				moveToChest(player, moveItems);
				saveChestData();
			}
		}
	}
	
	public void scanPlayerArmor(Player player) {
		PlayerInventory playerInv = player.getInventory();
		ItemStack delete = new ItemStack (Material.AIR);
		ItemStack is = playerInv.getHelmet();
		if (is != null) {
			if (confiscatable(player, is)) {
				playerInv.setHelmet(delete);
				moveToChest(player, is);
				saveChestData();
			}
		}
		is = playerInv.getChestplate();
		if (is != null) {
			if (confiscatable(player, is)) {
				playerInv.setChestplate(delete);
				moveToChest(player, is);
				saveChestData();
			}
		}
		is = playerInv.getLeggings();
		if (is != null) {
			if (confiscatable(player, is)) {
				playerInv.setLeggings(delete);
				moveToChest(player, is);
				saveChestData();
			}
		}
		is = playerInv.getBoots();
		if (is != null) {
			if (confiscatable(player, is)) {
				playerInv.setBoots(delete);
				moveToChest(player, is);
				saveChestData();
			}
		}
	}

	@SuppressWarnings("deprecation")
	public boolean confiscatable(Player player, ItemStack item) {
		
		File dataFile = new File("ConfiscationItems.yml");
		FileConfiguration list = YamlConfiguration.loadConfiguration(dataFile);
		
		ItemMeta im = item.getItemMeta();
		
		if (im != null) {
			if (im.getDisplayName() != null)
				if (im.getDisplayName().equals("WalkInPvP") || im.getDisplayName().equals("WalkInTeamsPvP") || im.getDisplayName().equals("Red Team WalkInTeamsPvP") || im.getDisplayName().equals("Blue Team WalkInTeamsPvP") || im.getDisplayName().equals("WalkInHockey"))
					return true;
			if (im.getLore() != null)
				if (im.getLore().get(0).equals(ChatColor.translateAlternateColorCodes('&', "&5&lmcMMO Ability Tool")))
					return false;
		
		}
		
		if (item.getTypeId() == 383) {
			if (player.getWorld().getName().equals("SkyBlock"))
				return false;
			if (item.getDurability() == (short) 100)
				return false;
		}
		
		if ((list.getList("confiscate.items").contains(item.getType().name()) 
				|| list.getList("confiscate.items").contains(item.getTypeId())) 
				&& !player.hasPermission("autoconfiscate.itemid." + item.getTypeId() + ".bypass")) {
			return true;
		}
		if (item.getMaxStackSize() < item.getAmount() && !item.getType().name().equals("POTION"))
			return true;
		if (!itemType(item).equals("other")) {
			if (checkEnchantments(player, item)) {
				return true;
			}
		} else {
			Map<Enchantment, Integer> enchantments = item.getEnchantments();
			if (enchantments.size() != 0)
				return true;
		}

		return false;
	}

	private static final Map<Integer, Integer> allEnchants = new HashMap<Integer, Integer>();
	static {
		allEnchants.put(0, 4);
		allEnchants.put(1, 4); // Boots
		allEnchants.put(2, 4);
		allEnchants.put(3, 4);
		allEnchants.put(4, 4);
		allEnchants.put(5, 3); // Helmet
		allEnchants.put(6, 1); // Helmet
		allEnchants.put(7, 3);
		allEnchants.put(34, 3);

		allEnchants.put(16, 5); // Axe
		allEnchants.put(17, 5); // Axe
		allEnchants.put(18, 5); // Axe
		allEnchants.put(19, 2);
		allEnchants.put(20, 2);
		allEnchants.put(21, 3);
		allEnchants.put(34, 3);

		allEnchants.put(32, 5);
		allEnchants.put(33, 1);
		allEnchants.put(34, 3);
		allEnchants.put(35, 3);

		allEnchants.put(34, 3);
		allEnchants.put(48, 5);
		allEnchants.put(49, 2);
		allEnchants.put(50, 1);
		allEnchants.put(51, 1);
	}

	public boolean checkEnchantments(Player player, ItemStack item){
		int maxEnchantAmount = -1;
		if (itemType(item).equals("armor"))
			maxEnchantAmount = 4;

		if (itemType(item).equals("weapon"))
			maxEnchantAmount = 4;

		if (itemType(item).equals("tool"))
			maxEnchantAmount = 3;
		
		if (getEnchantmentPermission(player, false) != -1) {
			maxEnchantAmount = getEnchantmentPermission(player, false);
		}

		if (item.getEnchantments().size() > maxEnchantAmount && maxEnchantAmount != -1 && !player.hasPermission("autoconfiscate.enchantmentnum.bypass")) {
			return true;
		}

		int maxEnchantNum = 0;
		Map<Enchantment, Integer> enchantments = item.getEnchantments();

		for (Map.Entry<Enchantment, Integer> enchantment : enchantments.entrySet()) {
			@SuppressWarnings("deprecation")
			int enchantmentNum = enchantment.getKey().getId();
			int enchantmentValue = enchantment.getValue();
			if (allEnchants.get(enchantmentNum) == enchantmentValue)
				maxEnchantNum++;
			if (allEnchants.get(enchantmentNum) < enchantmentValue)
				return true;
//			if (plugin.getConfig().getList("confiscate.disabled_enchantments") != null)
//				if (plugin.getConfig().getList("confiscate.disabled_enchantments").contains(enchantment.getKey().getName()))
//					return true;
		}

		int maxFullEnchant = -1;
		if (itemType(item).equals("armor"))
			maxFullEnchant = 3;

		if (itemType(item).equals("weapon"))
			maxFullEnchant = 3;

		if (itemType(item).equals("tool"))
			maxFullEnchant = -1;
		
		if (getEnchantmentPermission(player, true) != -1) {
			maxFullEnchant = getEnchantmentPermission(player, true);
		}
		
		if (maxEnchantNum > maxFullEnchant && maxFullEnchant != -1 && !player.hasPermission("autoconfiscate.enchantmentnum.bypass")) {
			return true;
		}
		
		if (hasIllegalEnchantments(item))
			return true;
		
		return false;
	}
	
	List<Integer> allArmor = Arrays.asList(0, 1, 3, 4, 7, 34);
	List<Integer> bootsExtras = Arrays.asList(2);
	List<Integer> helmetExtras = Arrays.asList(5, 6);
	List<Integer> sword = Arrays.asList(16, 17, 18, 19, 20, 21, 34);
	List<Integer> axe = Arrays.asList(16, 17, 18, 32, 33, 34, 35);
	List<Integer> bow = Arrays.asList(34, 48, 49, 50, 51);
	List<Integer> pickShovel = Arrays.asList(32, 33, 34, 35);
	List<Integer> shears = Arrays.asList(32, 33, 34);
	
	@SuppressWarnings("deprecation")
	public boolean hasIllegalEnchantments(ItemStack item) {
		Map<Enchantment, Integer> enchantments = item.getEnchantments();
		String name = item.getType().name();
		if (name.contains("HELMET") || name.contains("CHESTPLATE") || name.contains("LEGGINGS") || name.contains("BOOTS"))
			for (Map.Entry<Enchantment, Integer> enchantment : enchantments.entrySet()) {
				int id = enchantment.getKey().getId();
				if (!allArmor.contains(id))
					if (!(name.contains("BOOTS") && bootsExtras.contains(id)))
						if (!(name.contains("HELMET") && helmetExtras.contains(id)))
							return true;
			}
		if (name.contains("SWORD"))
			for (Map.Entry<Enchantment, Integer> enchantment : enchantments.entrySet()) {
				if (!sword.contains(enchantment.getKey().getId()))
					return true;
//				if (!(item.getType() == Material.GOLD_SWORD) 
//						&& enchantment.getKey().getId() == 16 && enchantment.getValue() == 5)
//					return true; //Sharpness V is not obtainable EXCEPT on gold swords
			}
		if (name.equals("BOW"))
			for (Map.Entry<Enchantment, Integer> enchantment : enchantments.entrySet()) {
				if (!bow.contains(enchantment.getKey().getId()))
					return true;
			}
		if (name.contains("AXE") && !name.contains("PICK"))
			for (Map.Entry<Enchantment, Integer> enchantment : enchantments.entrySet()) {
				if (!axe.contains(enchantment.getKey().getId()))
					return true;
//				if ((item.getType() == Material.STONE_AXE || item.getType() == Material.DIAMOND_AXE) 
//						&& enchantment.getKey().getId() == 32 && enchantment.getValue() == 5)
//					return true; //Efficiency V is not obtainable on stone or diamond tools
			}
		if (name.contains("PICK") || name.contains("SPADE"))
			for (Map.Entry<Enchantment, Integer> enchantment : enchantments.entrySet()) {
				if (!pickShovel.contains(enchantment.getKey().getId()))
					return true;
//				if ((item.getType() == Material.STONE_SPADE || item.getType() == Material.DIAMOND_SPADE
//						|| item.getType() == Material.STONE_PICKAXE || item.getType() == Material.DIAMOND_PICKAXE) 
//						&& enchantment.getKey().getId() == 32 && enchantment.getValue() == 5)
//					return true; //Efficiency V is not obtainable on stone or diamond tools
			}
		if (name.equals("SHEARS"))
			for (Map.Entry<Enchantment, Integer> enchantment : enchantments.entrySet()) {
				if (!shears.contains(enchantment.getKey().getId()))
					return true;
			}
		if (name.equals("FISHING_ROD") || name.contains("HOE") || name.equals("FLINT_AND_STEEL") || name.equals("CARROT_STICK"))
			for (Map.Entry<Enchantment, Integer> enchantment : enchantments.entrySet()) {
				if (enchantment.getKey().getId() != 33)
					return true;
			}
		return false;
	}

	public String itemType(ItemStack item){
		@SuppressWarnings("deprecation")
		int id = item.getTypeId();
		if (id == 267 ||
				id == 268 ||
				id == 272 ||
				id == 276 ||
				id == 261)
			return "weapon";
		if (id >= 298 && id <= 317)
			return "armor";
		if ((id >= 256 && id <= 258) || (id >= 269 && id <= 286) || (id >= 290 && id <= 2294))
			return "tool";
		return "other";
	}
	
	public int getEnchantmentPermission(Player player, boolean max) {
		if (max) {
			for (int i = 0; i < 25; i++) {
				if (player.hasPermission("autoconfiscate.maxfullenchantments." + i))
					return i;
			}
			return -1;
		} else {
			for (int i = 0; i < 25; i++) {
				if (player.hasPermission("autoconfiscate.maxenchantments." + i))
					return i;
			}
			return -1;
		}
	}
	
	@SuppressWarnings("deprecation")
	public void moveToChest(Player player, ItemStack items){
		World world = Bukkit.getWorld(getChestData().getString("first_chest.location.world"));
		int x;
		int y;
		int z;
//		int z = getChestData().getInt("first_chest.location.z");
		
		Chest chest = null;
		
		if (playerExists(player.getName())) {
			x = getChestData().getInt(player.getName() + ".chest_location.x");
			String isY = getChestData().getString(player.getName() + ".chest_location.y");
			if (isY == null) {
				getChestData().set(player.getName() + ".chest_location.y", getChestData().getInt("first_chest.location.y"));
			}
			y = getChestData().getInt(player.getName() + ".chest_location.y");
			z = getChestData().getInt(player.getName() + ".chest_location.z");
		} else {
			int yLayerNum = yLayerNum();
			int newY = getChestData().getInt("first_chest.location.y") + (yLayerNum * 4);
			int newZ = getChestData().getInt("first_chest.location.z");
			
			int maxXDistance = 120;
//			if (maxXDistance <= 3)
//				maxXDistance = 3;
			
			int newX = getChestData().getInt("first_chest.location.x") + (getChestData().getInt("players_confiscated") - (yLayerNum * (maxXDistance / 3))) * 3;
			
			getChestData().set("players_confiscated", getChestData().getInt("players_confiscated") + 1);
			
			generateChest(newX, newY, newZ, true);
			plugin.getLogger().info("New chest created at: " + newX + ", " + newY + ", " + newZ);
			
			Location signLoc = new Location(world, newX, newY+1, newZ);
			
			blockSet(newX, newY+1, newZ, 68);
			Sign sign = (Sign) signLoc.getBlock().getState();
			sign.setRawData((byte)3);
			sign.update();
			
			sign.setLine(0, ChatColor.WHITE + "-=-=-=-=-=-=-");
			sign.setLine(1, ChatColor.DARK_RED + "CONFISCATED:");
			sign.setLine(2, player.getName());
			sign.setLine(3, ChatColor.WHITE + "-=-=-=-=-=-=-");
			sign.update();
			
			getChestData().set(player.getName() + ".chest_location.x", newX);
			getChestData().set(player.getName() + ".chest_location.y", newY); 
			getChestData().set(player.getName() + ".chest_location.z", newZ); 
			getChestData().set(player.getName() + ".chest_location.num", 1); 
			
			if (getChestData().getInt("chest_range") < 1) 
				getChestData().set("chest_range", 1);
			saveChestData();
			
			x = newX;
			y = newY;
			z = newZ;
		}
		
		Location chestLoc = new Location(world, x, y, z);
		try{
			chest = (Chest) chestLoc.getBlock().getState();
		} catch (Exception e) {
			plugin.getLogger().info("Couldn't find chest at: " + x + ", " + y + ", " + z + ". Regenerating...");
			blockSet(x, y, z, 54);
			blockSet(x+1, y, z, 54);
			chest = (Chest) chestLoc.getBlock().getState();
		}
		
		Inventory chestInv = chest.getInventory();
		if (chestInv.firstEmpty() == -1) {
			plugin.getLogger().info("Chest full, creating new chest");
			int origz = getChestData().getInt(player.getName() + ".chest_location.z");
			int chestNum = getChestData().getInt(player.getName() + ".chest_location.num");
			
			chestNum++;
			
			getChestData().set(player.getName() + ".chest_location.z", origz + 2);
			getChestData().set(player.getName() + ".chest_location.num", chestNum);
			
			if (getChestData().getInt("chest_range") < chestNum) 
				getChestData().set("chest_range", chestNum);
			saveChestData();
			
			x = getChestData().getInt(player.getName() + ".chest_location.x");
			z = getChestData().getInt(player.getName() + ".chest_location.z");
			generateChest(x, y, z, false);
			
			chestLoc = new Location(world, x, y, z);
			chest = (Chest) chestLoc.getBlock().getState();
			chestInv = chest.getInventory();
		}
		
		chestInv.addItem(items);
	}
	
	public void addToList(Player player, ItemStack items) {
		ArrayList<String> itemList = (ArrayList<String>) getChestData().getStringList(player.getName() + ".confiscated_items");
		String itemName = getItemName(items);
			try {
				itemList.add(itemName);
			} catch (Exception e) {
				plugin.getLogger().warning("Failed to add: '" + itemName + "' to the chestdata.yml file");
			}
		getChestData().set(player.getName() + ".confiscated_items", itemList);
		saveChestData();
	}
	
	public void generateChest(int x, int y, int z, boolean starter){
//		int y = getChestData().getInt("first_chest.location.y");
		
		int backMat = 4;
		if (starter) {
			for (int x1 = x-1; x1 <= x+2; x1++)
				for (int y1 = y; y1 <= y+2; y1++)
					for (int z1 = z; z1 <= z+1; z1++)
						blockSet(x1, y1, z1, 0);
			
			for (int y1 = y; y1 <= y+2; y1++){
				for (int x1 = x-1; x1 <= x+2; x1++) {
					blockSet(x1, y1, z-1, backMat);
				}
			}
			blockSet(x, y+1, z, 0);
			blockSet(x+1, y+1, z, 50);
			blockSet(x, y+2, z, 0);
			blockSet(x+1, y+2, z, 0);
			
		} else {
			for (int x1 = x-1; x1 <= x+2; x1++)
				for (int y1 = y; y1 <= y+2; y1++)
					for (int z1 = z-1; z1 <= z+1; z1++)
						blockSet(x1, y1, z1, 0);
		}
		
		blockSet(x, y, z, 54);
		blockSet(x+1, y, z, 54);
		
		for (int z1 = z-1; z1 <= z+1; z1++) {
			for (int x1 = x-1; x1 <= x+2; x1++) {
				blockSet(x1, y-1, z1, backMat);
			}
		}
		saveChestData();
		
		
	}
	
	@SuppressWarnings("deprecation")
	public void blockSet(int x, int y, int z, int id){
		Block block = Bukkit.getWorld(getChestData().getString("first_chest.location.world")).getBlockAt(x, y, z);
//		if (!block.getChunk().isLoaded())
//			block.getChunk().load();
		block.setTypeId(id);
	}
	
	public boolean playerExists(String player) {
		String node = getChestData().getString(player + ".chest_location.x");
		return (node != null);
	}
	
	
	
	public void reloadChestData() {
	    if (chestDataFile == null) {
	    chestDataFile = new File("ConfiscationLog.yml");
	    }
	    chestData = YamlConfiguration.loadConfiguration(chestDataFile);
	 
	    InputStream defConfigStream = plugin.getResource("ConfiscationLog.yml");
	    if (defConfigStream != null) {
	        YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
	        chestData.setDefaults(defConfig);
	    }
	}
	public FileConfiguration getChestData() {
	    if (chestData == null) {
	        reloadChestData();
	    }
	    return chestData;
	}
	public void saveChestData() {
	    if (chestData == null || chestDataFile == null) {
//	    	reloadChestData();
	    	return;
	    }
	    try {
	        getChestData().save(chestDataFile);
	    } catch (IOException ex) {
	        plugin.getLogger().severe("Could not save config to " + chestDataFile);
	    }
	}
	
	public boolean isChestLogged(Chest chest) {
		reloadChestData();
		Location chestLoc = chest.getLocation();
		
		if (!chestLoc.getWorld().getName().equals(getChestData().getString("first_chest.location.world")))
			return false;
		
		int y = chestLoc.getBlockY();
		int minY = getChestData().getInt("first_chest.location.y");
		int maxY = minY + (yLayerNum() * 4);
		
		int x = chestLoc.getBlockX();
		int minX = getChestData().getInt("first_chest.location.x");
		int maxX = getChestData().getInt("players_confiscated") * 3 + minX - 2;
		
		int z = chestLoc.getBlockZ();
		int minZ = getChestData().getInt("first_chest.location.z");
		int maxZ = getChestData().getInt("chest_range") * 2 + minZ - 2;
		
//		plugin.getLogger().info("Found chest_range: " + getChestData().getInt("chest_range"));
//		plugin.getLogger().info("Found players_confiscated: " + getChestData().getInt("players_confiscated"));
//		plugin.getLogger().info("Found layer number: " + yLayerNum());
//		
//		plugin.getLogger().info("minX = " + minX + " x = " + x + " maxX = " + maxX);
//		plugin.getLogger().info("minZ = " + minZ + " z = " + z + " maxZ = " + maxZ);
//		plugin.getLogger().info("minY = " + minY + " y = " + y + " maxY = " + maxY);
		
		if (y < minY)
			return false;
		if (y > maxY)
			return false;
		
		if (z < minZ)
			return false;
		if (z > maxZ)
			return false;
		
		if (x < minX)
			return false;
		if (x > maxX)
			return false;
		
//		plugin.getLogger().info("Chest Logged");
		
		return true;
	}
	
	public String getItemName(ItemStack items) {
		String strEnchantments = "";
		Map<Enchantment, Integer> enchantments = items.getEnchantments();
		for (Map.Entry<Enchantment, Integer> enchantment : enchantments.entrySet())
			strEnchantments += enchantment.getKey().getName() + " " + enchantment.getValue() + "; ";
		String name = items.getAmount() + " " + items.getType().name();
		if (items.getDurability() != 0)
			name += ":"+ items.getDurability();
		if (strEnchantments != "")
			name += "; " + strEnchantments;
		return name;
	}
	
	public int yLayerNum() {
//		if (120 >= 3) {
		return (int) (getChestData().getInt("players_confiscated") / (120 / 3));
//		} else {
//			if (plugin.getConfig().getInt("chest_room.max_x_distance") == 0) {
//				return 0;
//			} else {
//				return getChestData().getInt("players_confiscated") - 1;
//			}
//		}
	}
	
	@EventHandler
	public void scanPlayerInventory(InventoryCloseEvent event) {
		scanInventory((Player) event.getPlayer(), event.getPlayer().getInventory());
	}
	
	@EventHandler
	public void onPlayerQuit(PlayerQuitEvent event) {
		scanInventory((Player) event.getPlayer(), event.getPlayer().getInventory());
	}

	@EventHandler
	public void scanChestContents(PlayerInteractEvent event) {
		Block b = event.getClickedBlock();
		if (b != null) {
			BlockState bs = b.getState();

			if (bs instanceof Chest) {
				Chest c = (Chest) bs;
				if (!isChestLogged(c)) {
					scanInventory(event.getPlayer(), c.getBlockInventory());

					BlockState bsNorth = b.getRelative(BlockFace.NORTH).getState();
					BlockState bsEast = b.getRelative(BlockFace.EAST).getState();
					BlockState bsSouth = b.getRelative(BlockFace.SOUTH).getState();
					BlockState bsWest = b.getRelative(BlockFace.WEST).getState();
					
					if (bsNorth instanceof Chest) {
						c = (Chest) bsNorth;
						scanInventory(event.getPlayer(), c.getBlockInventory());
					} else if (bsEast instanceof Chest) {
						c = (Chest) bsEast;
						scanInventory(event.getPlayer(), c.getBlockInventory());
					} else if (bsSouth instanceof Chest) {
						c = (Chest) bsSouth;
						scanInventory(event.getPlayer(), c.getBlockInventory());
					} else if (bsWest instanceof Chest) {
						c = (Chest) bsWest;
						scanInventory(event.getPlayer(), c.getBlockInventory());
					}
				}
			}
			if (bs instanceof BrewingStand) {
				BrewingStand bstand = (BrewingStand) bs;
				scanInventory(event.getPlayer(), bstand.getInventory());
			}
			if (bs instanceof Dispenser) {
				Dispenser d = (Dispenser) bs;
				scanInventory(event.getPlayer(), d.getInventory());
			}
			if (bs instanceof Furnace) {
				Furnace f = (Furnace) bs;
				scanInventory(event.getPlayer(), f.getInventory());
			}
			if (b.getType() == Material.ENDER_CHEST) {
				scanInventory(event.getPlayer(), event.getPlayer()
						.getEnderChest());
			}
		}
	}
	
	@EventHandler
	public void scanMinecart(PlayerInteractEntityEvent event) {
		Entity mc = event.getRightClicked();
		if (mc instanceof StorageMinecart){
			scanInventory(event.getPlayer(), ((StorageMinecart) mc).getInventory());
		}
	}
	
	
	public void log(String info) {
		plugin.getLogger().info("<AutoConfiscate> " + info);
	}
} public class GameTime {
	private CustomPlugin plugin;

	public GameTime(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	@SuppressWarnings("deprecation")
	public void enable() {
		Calendar time = Calendar.getInstance();
		int hour = time.get(Calendar.HOUR_OF_DAY);
		hour = hour + 1;
		if (hour < 0)
			hour = 24 + hour;
		log("<GameTime> Hour is: " + hour);
		if (hour <= 7 || hour >= 20) {
			log("<GameTime> Setting EventWorld to night");
			plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {
				@Override 
				public void run() {
					Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tl set EventWorld night");
				}
			}, 60 * 20 * 1);
		} else {
			log("<GameTime> Setting EventWorld to day");
			plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {
				@Override 
				public void run() {
					Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tl set EventWorld day");
				}
			}, 60 * 20 * 1);
		}
		log("<GameTime> Enabled");
		log("Enabled");
	}

	public void log(String info) {
		plugin.log("<GameTime> " + info);
	}
} public class IpRecorder {
	private CustomPlugin plugin;
	
	private static File File;
	private static FileConfiguration YMLFile;

	public IpRecorder(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		loadIps();
		log("Enabled");
	}
	
	public void loadIps() {
		try {
			File = new File("ips.yml");
			YMLFile = YamlConfiguration.loadConfiguration(File);
		} catch (Exception e) {
			log("Ips failed to load :/");
		}
	}
	
	public void saveIps() {
		try {
			YMLFile.save(File);
		} catch (Exception e) {
			log("Ips failed to save :/");
		}
	}
		
	public void onPlayerJoinEvent(PlayerJoinEvent event) {
		YMLFile.set(event.getPlayer().getName(), event.getPlayer().getAddress().getAddress().getHostAddress());
		saveIps();
	}

	public void log(String info) {
		plugin.getLogger().info("<IpRecorder> " + info);
	}
} public class RestartWarning {
	private CustomPlugin plugin;

	public RestartWarning(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	public boolean onCommand(CommandSender sender) {
		if (!(sender instanceof Player)) {
			Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', "&1&l==&4&oWARNING&1&l== &cServer restarting in 1 minute! &1&l==&4&oWARNING&1&l=="));
			plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
				@Override 
				public void run() {
					Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "plugman unload PvPReward");
				}
			}, 60 * 20 * 1 - 3);
		}
		return true;
	}

	public void log(String info) {
		plugin.getLogger().info("<RestartWarning> " + info);
	}
} public class UnderCover {
	private CustomPlugin plugin;

	public UnderCover(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		log("Enabled");
	}
	
	public boolean onCommand(CommandSender sender) {
		if (sender instanceof Player) {
			if (((Player) sender).getName().equals("Esaych")) {
				Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', "     &c-&r &5Esaych"));
				setPlayerName((EntityPlayer) ((CraftPlayer) sender).getHandle(), "Hycase");
			}
		}
		return true;
	}

	private void setPlayerName(EntityPlayer player, String newname) {
		WorldServer world = (WorldServer) player.world;
		EntityTracker tracker = world.tracker;
		tracker.untrackEntity(player);
//		player.name = newname;
		player.displayName = ChatColor.GRAY + newname;
		Bukkit.dispatchCommand(player.getBukkitEntity(), "fullprefix &7Hycase");
		Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "plugman reload mcmmo");
		player.getBukkitEntity().setPlayerListName(ChatColor.GRAY + newname);
		tracker.track(player);
	}
	
	public void log(String info) {
		plugin.getLogger().info("<UnderCover> " + info);
	}
} public class VirtualChest {
	private CustomPlugin plugin;
	
	private FileConfiguration chestData = null;
	private File chestDataFile = null;
	
	private int chestX = 0;
	private int chestY = 254;
	private int chestZ = 0;
	private String chestWorld = "Build";

	public VirtualChest(CustomPlugin plugin) {
		this.plugin = plugin;
	}

	public void enable() {
		reloadChestData();
		saveChestData();
		log("Enabled");
	}
	
	public boolean onVCCommand(CommandSender sender, String[] args) {
		boolean isAdmin = sender.hasPermission("customplugin.virtualchest.admin");
		if ((args.length == 0) || (args.length > 0 && args[0].equalsIgnoreCase("help"))) {
			msg(sender, "&6======== &aVirtual Chest Help &6========");
			msg(sender, "'&b/vc info&f'/'&b/vc status&f' - See info on your Virtual Chests");
			msg(sender, "'&b/vc open [number]&f' - Open Virtual Chest");
			msg(sender, "'&b/vc new&f' - Add a new chest");
			msg(sender, "Virtual Chest opens a chest which you can store your extra inventory contents and store items until after your deaths and server restarts for later use.");
			msg(sender, "Removing all items from your last chest will delete it. Other chests will remain empty.");
//			msg(sender, "This way chest numbers stay organized.");
			if (isAdmin) {
				msg(sender, "&6======== &c&lAdmin Commands &6========");
				msg(sender, "'&b/vc info [player]&f' - See other player's chest info");
				msg(sender, "'&b/vc open [number] [player]&f' - Open another player's chests");
			}
			msg(sender, "&6=================================");
			return true;
		}
		if (!(sender instanceof Player)) {
			msg(sender, "Consoles don't have anything to store.");
			return true;
		}
		Player player = (Player)sender;
		if (!player.hasPermission("customplugin.virtualchest")) {
			msg(player, "You may not use Virtual Chests here.");
			return true;
		}
		if (args[0].equalsIgnoreCase("info") || args[0].equalsIgnoreCase("status")) {
			if (isAdmin && args.length > 1) {
				Player search = Bukkit.getPlayer(args[1]);
				if (search != null) {
					showInfo(player, search.getName());
				} else if (playerExists(args[1])) {
					showInfo(player, args[1]);
				} else {
					msg(player, args[1] + " does not exist/have a chest");
				}
			} else {
				showInfo(player, player.getName());
			}
			return true;
		} else if (args[0].equalsIgnoreCase("open")) {
			int chestNum = 0;
			try {
				chestNum = Integer.parseInt(args[1]);
			} catch (Exception e) {
				msg(player, "Please specify a chest number");
				return true;
			}
			if (isAdmin && args.length > 2) {
				Player search = Bukkit.getPlayer(args[2]);
				if (search != null) {
					String searchChest = "";
					int chestNum2 = 0;
					while (searchChest != null) {
						chestNum2++;
						searchChest = getChestData().getString(search.getName() + "." + chestNum2 + ".x");
					}
					Inventory inv = getChestInv(search.getName(), chestNum);
					if (chestNum < chestNum2 && chestNum > 0) {
						player.openInventory(inv);
					} else {
						msg(player, "That chest does not exist");
					}
				} else if (playerExists(args[2])) {
					String searchChest = "";
					int chestNum2 = 0;
					while (searchChest != null) {
						chestNum2++;
						searchChest = getChestData().getString(args[2] + "." + chestNum2 + ".x");
					}
					Inventory inv = getChestInv(args[2], chestNum);
					if (chestNum < chestNum2 && chestNum > 0) {
						player.openInventory(inv);
					} else {
						msg(player, "That chest does not exist");
					}
				} else {
					msg(player, args[2] + " does not exist/have a chest");
				}
			} else {
				String searchChest = "";
				int chestNum2 = 0;
				while (searchChest != null) {
					chestNum2++;
					searchChest = getChestData().getString(player.getName() + "." + chestNum2 + ".x");
				}
				Inventory inv = getChestInv(player.getName(), chestNum);
				if (chestNum < chestNum2 && chestNum > 0) {
					player.openInventory(inv); 
				} else {
					msg(player, "That chest does not exist");
				}
			}
			return true;
		} else if (args[0].equalsIgnoreCase("new")) {
			
			String search = "";
			int chestNum = 0;
			while (search != null) {
				chestNum++;
				search = getChestData().getString(player.getName() + "." + chestNum + ".x");
			}
			chestNum--;
			for(int i = 1; i <= chestNum; i++) {
				Inventory inv = getChestInv(player.getName(), chestNum);
				if (inv == null) {
					int x = getChestData().getInt(player.getName() + "." + chestNum + "x");
					int y = chestY;
					int z = getChestData().getInt(player.getName() + "." + chestNum + "z");
					plugin.getLogger().info("Couldn't find chest at: " + x + ", " + y + ", " + z + ". Regenerating...");
					blockSet(x, y, z, 54);
					blockSet(x+1, y, z, 54);
					inv = getChestInv(player.getName(), i);
				}
				int contSize = 0;
				for (ItemStack item : inv.getContents()) {
					if (item != null) {
						contSize++;
					}
				}
				if (contSize < 40) {
					msg(player, "All chests must have atleast 40 slots full before creating a new chest!");
					return true;
				}
			}
			
			
			
			search = "";
			chestNum = 0;
			while (search != null) {
				chestNum++;
				search = getChestData().getString(player.getName() + "." + chestNum + ".x");
			}
			chestNum--;
			if (chestNum == 0) {
				getChestInv(player.getName(), 1);
				msg(player, "New chest &b1&f created.");
				return true;
			}
			int origz = chestZ - (2 * chestNum) - 2;
			
			chestNum++;

			getChestData().set(player.getName() + "." + chestNum + ".x", getChestData().getInt(player.getName() + "." + (chestNum-1) + ".x"));
			getChestData().set(player.getName() + "." + chestNum + ".z", origz + 2);
			saveChestData();
			
			int x = getChestData().getInt(player.getName() + "." + chestNum + ".x");
			int y = chestY;
			int z = getChestData().getInt(player.getName() + "." + chestNum + ".z");
			generateChest(x, y, z, false);
			
//			Location chestLoc = new Location(Bukkit.getWorld(chestWorld), x, y, z);
//			Chest chest = (Chest) chestLoc.getBlock().getState();
//			chestInv = chest.getInventory();
			msg(player, "New chest &b" + chestNum + "&f created.");
			return true;
		} else {
			msg(player, "Type &b/vc help");
			return true;
		}
	}
	
	public void showInfo(Player player, String lookup) {
		msg(player, "Showing information for: &b" + lookup);
		String search = "";
		int chestNum = 0;
		while (search != null) {
			chestNum++;
			search = getChestData().getString(lookup + "." + chestNum + ".x");
		}
		chestNum--;
		msg(player, "Amount of chests: " + chestNum);
		for(int i = 1; i <= chestNum; i++) {
			Inventory inv = getChestInv(lookup, i);
			if (inv == null) {
				int x = getChestData().getInt(player.getName() + "." + i + "x");
				int y = chestY;
				int z = getChestData().getInt(player.getName() + "." + i + "z");
				plugin.getLogger().info("Couldn't find chest at: " + x + ", " + y + ", " + z + ". Regenerating...");
				blockSet(x, y, z, 54);
				blockSet(x+1, y, z, 54);
				inv = getChestInv(lookup, i);
			}
			int invSize = inv.getSize();
			int contSize = 0;
			for (ItemStack item : inv.getContents()) {
				if (item != null) {
					contSize++;
				}
			}
			if (invSize == contSize) {
				msg(player, "Chest " + i + ": &cFULL");
			} else if (contSize == 0){
				msg(player, "Chest " + i + ": &aEMPTY");
			} else {
				msg(player, "Chest " + i + ": " + contSize + "/" + invSize + " slots used");
			}
		}
	}
	
	@SuppressWarnings("deprecation")
	public Inventory getChestInv(String playerName, int chestNum){
		World world = Bukkit.getWorld(chestWorld);
		int x;
		int y;
		int z;
//		int z = getChestData().getInt("first_chest.location.z");
		
		Chest chest = null;
		
		if (playerExists(playerName)) {
//			String search = "";
//			int chestNum = 0;
//			while (search != null) {
//				chestNum++;
//				search = getChestData().getString(player.getName() + "." + chestNum + ".x");
//			}
			x = getChestData().getInt(playerName + "." + chestNum + ".x");
			y = chestY;
			z = getChestData().getInt(playerName + "." + chestNum + ".z");
		} else {
			int newZ = chestZ;
			int newX = chestX + (getChestData().getInt("playerNum") * 3);
			int newY = chestY;
			
			if (getChestData().getString("playerNum") == null) {
				getChestData().set("playerNum", 1);
			} else {
				getChestData().set("playerNum", getChestData().getInt("playerNum") + 1);
			}
			
			generateChest(newX, newY, newZ, true);
			plugin.getLogger().info("New chest created at: " + newX + ", " + newY + ", " + newZ);
			
			Location signLoc = new Location(world, newX, newY, newZ+1);
			
			blockSet(newX, newY, newZ+1, 68);
			Sign sign = (Sign) signLoc.getBlock().getState();
			sign.setRawData((byte)3);
			sign.update();
			
			sign.setLine(0, ChatColor.WHITE + "-=-=-=-=-=-=-");
			sign.setLine(1, ChatColor.GREEN + "VirtualChest:");
			sign.setLine(2, playerName);
			sign.setLine(3, ChatColor.WHITE + "-=-=-=-=-=-=-");
			sign.update();
			
			getChestData().set(playerName + ".1.x", newX);
			getChestData().set(playerName + ".1.z", newZ); 
			
			saveChestData();
			
			x = newX;
			y = newY;
			z = newZ;
		}
		
		Location chestLoc = new Location(world, x, y, z);
		try {
			chest = (Chest) chestLoc.getBlock().getState();
		} catch (Exception e) {
//			plugin.getLogger().info("Couldn't find chest at: " + x + ", " + y + ", " + z + ". Regenerating...");
//			blockSet(x, y, z, 54);
//			blockSet(x+1, y, z, 54);
//			chest = (Chest) chestLoc.getBlock().getState();
			return null;
		}
		return chest.getInventory();
	}
	
	public void generateChest(int x, int y, int z, boolean starter){
//		int y = getChestData().getInt("first_chest.location.y");
		
//		int backMat = 4;
		if (starter) {
//			for (int x1 = x-1; x1 <= x+2; x1++)
//				for (int y1 = y; y1 <= y+2; y1++)
//					for (int z1 = z; z1 <= z+1; z1++)
//						blockSet(x1, y1, z1, 0);
//			
//			for (int y1 = y; y1 <= y+2; y1++){
//				for (int x1 = x-1; x1 <= x+2; x1++) {
//					blockSet(x1, y1, z-1, backMat);
//				}
//			}
			blockSet(x, y+1, z, 0);
			blockSet(x, y+2, z, 0);
			blockSet(x+1, y+2, z, 0);
			
		} else {
			for (int x1 = x-1; x1 <= x+2; x1++)
				for (int y1 = y; y1 <= y+2; y1++)
					for (int z1 = z-1; z1 <= z+1; z1++)
						blockSet(x1, y1, z1, 0);
		}
		
		blockSet(x, y, z, 54);
		blockSet(x+1, y, z, 54);
		
//		for (int z1 = z-1; z1 <= z+1; z1++) {
//			for (int x1 = x-1; x1 <= x+2; x1++) {
//				blockSet(x1, y-1, z1, backMat);
//			}
//		}
		saveChestData();
		
		
	}
	
	@SuppressWarnings("deprecation")
	public void blockSet(int x, int y, int z, int id){
		Block block = Bukkit.getWorld(chestWorld).getBlockAt(x, y, z);
//		if (!block.getChunk().isLoaded())
//			block.getChunk().load();
		block.setTypeId(id);
	}
	
	public boolean playerExists(String player) {
		String node = getChestData().getString(player + ".1.x");
		return (node != null);
	}
	
	public void reloadChestData() {
	    if (chestDataFile == null) {
	    chestDataFile = new File("VirtualChests.yml");
	    }
	    chestData = YamlConfiguration.loadConfiguration(chestDataFile);
	 
	    InputStream defConfigStream = plugin.getResource("VirtualChests.yml");
	    if (defConfigStream != null) {
	        YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
	        chestData.setDefaults(defConfig);
	    }
	}
	public FileConfiguration getChestData() {
	    if (chestData == null) {
	        reloadChestData();
	    }
	    return chestData;
	}
	public void saveChestData() {
	    if (chestData == null || chestDataFile == null) {
//	    	reloadChestData();
	    	return;
	    }
	    try {
	        getChestData().save(chestDataFile);
	    } catch (IOException ex) {
	        plugin.getLogger().severe("Could not save config to " + chestDataFile);
	    }
	}
	
	
	public void msg(CommandSender sender, String msg) {
		if (sender instanceof Player) {
			Player player = (Player) sender;
			player.sendMessage(ChatColor.DARK_GREEN + "[" + ChatColor.GREEN + "VirtualChest" + ChatColor.DARK_GREEN + "] " + ChatColor.WHITE + ChatColor.translateAlternateColorCodes('&', msg));
		} else {
			log(msg);
		}
	}

	public void log(String info) {
		plugin.getLogger().info("<VirtualChest> " + info);
	}
}	 public class DataManager {
	private FileConfiguration data = null;
	private File dataFile = null;
	
	public void reloaddata() {
	    if (dataFile == null) {
	    	dataFile = new File("/home/Bungee/customplugin/data.yml");
	    }
	    data = YamlConfiguration.loadConfiguration(dataFile);
	}
	
	public FileConfiguration cpgetdata() {
		reloaddata();
	    return data;
	}
	
	public void cpsavedata() {
	    try {
	        cpgetdata().save(dataFile);
	    } catch (IOException ex) {
	        System.out.println("Could not save config to " + dataFile);
	        System.out.println(ex.toString());
	    }
	}
	
	public void set(String plugin, String data, Object ob) {
		cpgetdata().set(plugin + data, ob);
		cpsavedata();
	}
	
	public Object get(String plugin, String data) {
		return cpgetdata().get(plugin + data);
	}

}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import net.diamonddominion.esaych.creative.CreativeEntityRemover;
import net.diamonddominion.esaych.creative.PlotMeOverride;
import net.diamonddominion.esaych.destruction.TnTPunch;
import net.diamonddominion.esaych.events.EWBlockFenceWalk;
import net.diamonddominion.esaych.events.EWButtons;
import net.diamonddominion.esaych.global.BeastSprint;
import net.diamonddominion.esaych.global.BungeeGlobalCommand;
import net.diamonddominion.esaych.global.Chat;
import net.diamonddominion.esaych.global.ChatPrefix;
import net.diamonddominion.esaych.global.ColorArmor;
import net.diamonddominion.esaych.global.CommandModifier;
import net.diamonddominion.esaych.global.CrashPlayer;
import net.diamonddominion.esaych.global.CustomRecipies;
import net.diamonddominion.esaych.global.FullMute;
import net.diamonddominion.esaych.global.HeartBeat;
import net.diamonddominion.esaych.global.Homes;
import net.diamonddominion.esaych.global.HubPortals;
import net.diamonddominion.esaych.global.LaunchPad;
import net.diamonddominion.esaych.global.Nameless;
import net.diamonddominion.esaych.global.RespectedAutoPromote;
import net.diamonddominion.esaych.global.ServerRestart;
import net.diamonddominion.esaych.global.SignEdit;
import net.diamonddominion.esaych.global.SpawnerSwitch;
import net.diamonddominion.esaych.global.Trampoline;
import net.diamonddominion.esaych.global.Voodoo;
import net.diamonddominion.esaych.global.VoteRewards;
import net.diamonddominion.esaych.skyblock.SkyBlockPortalReward;
import net.diamonddominion.esaych.skyblock.SkyBlockTP;
import net.diamonddominion.esaych.survival.DemiGodPackage;
import net.diamonddominion.esaych.survival.DirectionBook;
import net.diamonddominion.esaych.survival.DonorShop;
import net.diamonddominion.esaych.survival.EndDragonRespawn;
import net.diamonddominion.esaych.survival.EnderEggCollection;
import net.diamonddominion.esaych.survival.ExtraMiningLoot;
import net.diamonddominion.esaych.survival.FairFly;
import net.diamonddominion.esaych.survival.FairGod;
import net.diamonddominion.esaych.survival.ModAppWall;
import net.diamonddominion.esaych.survival.ModListWall;
import net.diamonddominion.esaych.survival.SpawnMusic;
import net.diamonddominion.esaych.survival.StaffVotes;
import net.diamonddominion.esaych.survival.TopPvPers;
import net.diamonddominion.esaych.survival.VoteReceiver;
import net.diamonddominion.esaych.survival.WarpWild;
import net.diamonddominion.esaych.survival.WelcomeBook;
import net.diamonddominion.esaych.survival.WelcomeSign;
import net.diamonddominion.esaych.unused.AutoConfiscate;
import net.diamonddominion.esaych.unused.GameTime;
import net.diamonddominion.esaych.unused.IpRecorder;
import net.diamonddominion.esaych.unused.RestartWarning;
import net.diamonddominion.esaych.unused.UnderCover;
import net.diamonddominion.esaych.unused.VirtualChest;
import net.diamonddominion.esaych.util.DataManager;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityCreatePortalEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityPortalEnterEvent;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.ItemDespawnEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.messaging.PluginMessageListener;
import org.bukkit.scheduler.BukkitTask;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
package net.diamonddominion.esaych;







/**
 * Class, that loads all custom plugins, 
 * send commands and events to all custom plugins, 
 * and disables them and clears all tasks.
 */

public class CustomPlugin extends JavaPlugin implements Listener, PluginMessageListener {

	//	private CustomPlugin plugin;
	//	
	//	public ___(CustomPlugin plugin) {
	//		this.plugin = plugin;
	//	}
	//	
	//	public void enable() {
	//		log("Enabled");
	//	}
	//	
	//	public void log(String info) {
	//		plugin.getLogger().info("<___> " + info);
	//	}
	
	//	public DrunkenWizard drunkenWizard = new DrunkenWizard(this);
	//	public JailSigns jailSigns = new JailSigns(this);
//	public LegitWarzone legitWarzone;
	//	public PeacefulGriefFree peacefulGriefFree = new PeacefulGriefFree(this);
	//	public TabNameFix tabNameFix = new TabNameFix(this);
	public AutoConfiscate autoConfiscate;
    public BeastSprint beastSprint;
    public Chat chat;
    public ChatPrefix chatPrefix;
    public ColorArmor colorArmor;
    public CommandModifier commandModifier;
    public CrashPlayer crashPlayer;
    public CreativeEntityRemover creativeEntityRemover;
    public CustomRecipies customRecipies;
    public DemiGodPackage demiGod;
    public DirectionBook directionBook;
    public DonorShop donorShop;
    public EndDragonRespawn endDragonRespawn;
    public EnderEggCollection enderEggCollection;
    public EWBlockFenceWalk ewBlockFenceWalk;