/* * Copyright (C) 2016 eccentric_nz * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package me.eccentric_nz.TARDIS.destroyers; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.UUID; import me.eccentric_nz.TARDIS.TARDIS; import me.eccentric_nz.TARDIS.builders.TARDISInteriorPostioning; import me.eccentric_nz.TARDIS.builders.TARDISTIPSData; import me.eccentric_nz.TARDIS.database.QueryFactory; import me.eccentric_nz.TARDIS.database.ResultSetBlocks; import me.eccentric_nz.TARDIS.database.ResultSetCurrentLocation; import me.eccentric_nz.TARDIS.database.ResultSetGravity; import me.eccentric_nz.TARDIS.database.ResultSetTardis; import me.eccentric_nz.TARDIS.database.ResultSetTravellers; import me.eccentric_nz.TARDIS.database.data.ReplacedBlock; import me.eccentric_nz.TARDIS.database.data.Tardis; import me.eccentric_nz.TARDIS.enumeration.COMPASS; import me.eccentric_nz.TARDIS.enumeration.SCHEMATIC; import me.eccentric_nz.TARDIS.utility.TARDISMessage; import me.eccentric_nz.TARDIS.utility.TARDISNumberParsers; import me.eccentric_nz.tardischunkgenerator.TARDISChunkGenerator; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.WorldType; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; /** * The Daleks were a warlike race who waged war across whole civilisations and * races all over the universe. Advance and Attack! Attack and Destroy! Destroy * and Rejoice! * * @author eccentric_nz */ public class TARDISExterminator { private final TARDIS plugin; public TARDISExterminator(TARDIS plugin) { this.plugin = plugin; } public boolean exterminate(int id) { HashMap<String, Object> where = new HashMap<String, Object>(); where.put("tardis_id", id); ResultSetTardis rs = new ResultSetTardis(plugin, where, "", false, 2); try { if (rs.resultSet()) { Tardis tardis = rs.getTardis(); boolean hid = tardis.isHidden(); String chunkLoc = tardis.getChunk(); String owner = tardis.getOwner(); UUID uuid = tardis.getUuid(); int tips = tardis.getTIPS(); boolean hasZero = (!tardis.getZero().isEmpty()); SCHEMATIC schm = tardis.getSchematic(); HashMap<String, Object> wherecl = new HashMap<String, Object>(); wherecl.put("tardis_id", id); ResultSetCurrentLocation rsc = new ResultSetCurrentLocation(plugin, wherecl); if (!rsc.resultSet()) { return false; } Location bb_loc = new Location(rsc.getWorld(), rsc.getX(), rsc.getY(), rsc.getZ()); final DestroyData dd = new DestroyData(plugin, uuid.toString()); dd.setChameleon(false); dd.setDirection(rsc.getDirection()); dd.setLocation(bb_loc); dd.setPlayer(plugin.getServer().getOfflinePlayer(uuid)); dd.setHide(false); dd.setOutside(false); dd.setSubmarine(rsc.isSubmarine()); dd.setTardisID(id); dd.setBiome(rsc.getBiome()); if (!hid) { plugin.getPresetDestroyer().destroyPreset(dd); } cleanHashMaps(id); String[] chunkworld = chunkLoc.split(":"); World cw = plugin.getServer().getWorld(chunkworld[0]); int restore = getRestore(cw); if (cw == null) { plugin.debug("The server could not find the TARDIS world, has it been deleted?"); return false; } if (!cw.getName().contains("TARDIS_WORLD_")) { plugin.getInteriorDestroyer().destroyInner(schm, id, cw, restore, owner, tips); } cleanWorlds(cw, owner); removeZeroRoom(tips, hasZero); cleanDatabase(id); return true; } } catch (Exception e) { plugin.getConsole().sendMessage(plugin.getPluginName() + "TARDIS exterminate by id error: " + e); return false; } return true; } /** * Deletes a TARDIS. * * @param player running the command. * @param block the block that represents the Police Box sign * @return true or false depending on whether the TARIS could be deleted */ @SuppressWarnings("deprecation") public boolean exterminate(final Player player, Block block) { int signx = 0, signz = 0; Location sign_loc = block.getLocation(); HashMap<String, Object> where = new HashMap<String, Object>(); ResultSetTardis rs; if (player.hasPermission("tardis.delete")) { Block blockbehind = null; byte data = block.getData(); if (data == 4) { blockbehind = block.getRelative(BlockFace.EAST, 2); } if (data == 5) { blockbehind = block.getRelative(BlockFace.WEST, 2); } if (data == 3) { blockbehind = block.getRelative(BlockFace.NORTH, 2); } if (data == 2) { blockbehind = block.getRelative(BlockFace.SOUTH, 2); } if (blockbehind != null) { Block blockDown = blockbehind.getRelative(BlockFace.DOWN, 2); Location bd_loc = blockDown.getLocation(); HashMap<String, Object> wherecl = new HashMap<String, Object>(); wherecl.put("world", bd_loc.getWorld().getName()); wherecl.put("x", bd_loc.getBlockX()); wherecl.put("y", bd_loc.getBlockY()); wherecl.put("z", bd_loc.getBlockZ()); ResultSetCurrentLocation rsc = new ResultSetCurrentLocation(plugin, wherecl); if (!rsc.resultSet()) { TARDISMessage.send(player, "CURRENT_NOT_FOUND"); return false; } where.put("tardis_id", rsc.getTardis_id()); rs = new ResultSetTardis(plugin, where, "", false, 2); } else { TARDISMessage.send(player, "CURRENT_NOT_FOUND"); return false; } } else { where.put("uuid", player.getUniqueId().toString()); rs = new ResultSetTardis(plugin, where, "", false, 0); } if (rs.resultSet()) { Tardis tardis = rs.getTardis(); final int id = tardis.getTardis_id(); String owner = tardis.getOwner(); String chunkLoc = tardis.getChunk(); int tips = tardis.getTIPS(); boolean hasZero = (!tardis.getZero().isEmpty()); SCHEMATIC schm = tardis.getSchematic(); // need to check that a player is not currently in the TARDIS if (player.hasPermission("tardis.delete")) { HashMap<String, Object> travid = new HashMap<String, Object>(); travid.put("tardis_id", id); ResultSetTravellers rst = new ResultSetTravellers(plugin, travid, false); if (rst.resultSet()) { TARDISMessage.send(player, "TARDIS_NO_DELETE"); return false; } } // check the sign location HashMap<String, Object> wherecl = new HashMap<String, Object>(); wherecl.put("tardis_id", id); ResultSetCurrentLocation rsc = new ResultSetCurrentLocation(plugin, wherecl); if (!rsc.resultSet()) { TARDISMessage.send(player, "CURRENT_NOT_FOUND"); return false; } Location bb_loc = new Location(rsc.getWorld(), rsc.getX(), rsc.getY(), rsc.getZ()); // get TARDIS direction COMPASS d = rsc.getDirection(); switch (d) { case EAST: signx = -2; signz = 0; break; case SOUTH: signx = 0; signz = -2; break; case WEST: signx = 2; signz = 0; break; case NORTH: signx = 0; signz = 2; break; } int signy = -2; // if the sign was on the TARDIS destroy the TARDIS! final DestroyData dd = new DestroyData(plugin, player.getUniqueId().toString()); dd.setChameleon(false); dd.setDirection(d); dd.setLocation(bb_loc); dd.setPlayer(player); dd.setHide(true); dd.setOutside(false); dd.setSubmarine(rsc.isSubmarine()); dd.setTardisID(id); dd.setBiome(rsc.getBiome()); if (sign_loc.getBlockX() == bb_loc.getBlockX() + signx && sign_loc.getBlockY() + signy == bb_loc.getBlockY() && sign_loc.getBlockZ() == bb_loc.getBlockZ() + signz) { if (!tardis.isHidden()) { // remove Police Box plugin.getPresetDestroyer().destroyPreset(dd); } else { // restore biome plugin.getUtils().restoreBiome(bb_loc, rsc.getBiome()); } String[] chunkworld = chunkLoc.split(":"); World cw = plugin.getServer().getWorld(chunkworld[0]); if (cw == null) { TARDISMessage.send(player, "WORLD_DELETED"); return true; } int restore = getRestore(cw); if (!cw.getName().contains("TARDIS_WORLD_")) { plugin.getInteriorDestroyer().destroyInner(schm, id, cw, restore, owner, tips); } cleanWorlds(cw, owner); removeZeroRoom(tips, hasZero); plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { @Override public void run() { cleanDatabase(id); TARDISMessage.send(player, "TARDIS_EXTERMINATED"); } }, 40L); return false; } else { // cancel the event because it's not the player's TARDIS TARDISMessage.send(player, "NOT_OWNER"); return false; } } else { TARDISMessage.send(player, "NO_GRIEF"); return false; } } private int getRestore(World w) { World.Environment env = w.getEnvironment(); if (w.getWorldType() == WorldType.FLAT || w.getName().equals("TARDIS_TimeVortex") || w.getGenerator() instanceof TARDISChunkGenerator) { return 0; } switch (env) { case NETHER: return 87; case THE_END: return 121; default: return 1; } } public void cleanHashMaps(int id) { // remove protected blocks from the HashMap HashMap<String, Object> whereb = new HashMap<String, Object>(); whereb.put("tardis_id", id); ResultSetBlocks rsb = new ResultSetBlocks(plugin, whereb, true); if (rsb.resultSet()) { for (ReplacedBlock rp : rsb.getData()) { plugin.getGeneralKeeper().getProtectBlockMap().remove(rp.getStrLocation()); } } // remove gravity well blocks from the HashMap HashMap<String, Object> whereg = new HashMap<String, Object>(); whereg.put("tardis_id", id); ResultSetGravity rsg = new ResultSetGravity(plugin, whereg, true); if (rsg.resultSet()) { ArrayList<HashMap<String, String>> gdata = rsg.getData(); for (HashMap<String, String> gmap : gdata) { int direction = TARDISNumberParsers.parseInt(gmap.get("direction")); switch (direction) { case 1: plugin.getGeneralKeeper().getGravityUpList().remove(gmap.get("location")); break; case 2: plugin.getGeneralKeeper().getGravityNorthList().remove(gmap.get("location")); break; case 3: plugin.getGeneralKeeper().getGravityWestList().remove(gmap.get("location")); break; case 4: plugin.getGeneralKeeper().getGravitySouthList().remove(gmap.get("location")); break; case 5: plugin.getGeneralKeeper().getGravityEastList().remove(gmap.get("location")); break; default: plugin.getGeneralKeeper().getGravityDownList().remove(gmap.get("location")); break; } } } } public void cleanDatabase(int id) { QueryFactory qf = new QueryFactory(plugin); List<String> tables = Arrays.asList("ars", "back", "blocks", "chameleon", "chunks", "controls", "current", "destinations", "doors", "gravity_well", "homes", "junk", "lamps", "next", "tardis", "thevoid", "travellers", "vaults"); // remove record from database tables for (String table : tables) { HashMap<String, Object> where = new HashMap<String, Object>(); where.put("tardis_id", id); qf.doDelete(table, where); } } private void cleanWorlds(World w, String owner) { // remove world guard region protection if (plugin.isWorldGuardOnServer() && plugin.getConfig().getBoolean("preferences.use_worldguard")) { plugin.getWorldGuardUtils().removeRegion(w, owner); plugin.getWorldGuardUtils().removeRoomRegion(w, owner, "renderer"); } // unload and remove the world if it's a TARDIS_WORLD_ world if (w.getName().contains("TARDIS_WORLD_")) { String name = w.getName(); List<Player> players = w.getPlayers(); Location spawn = plugin.getServer().getWorlds().get(0).getSpawnLocation(); for (Player p : players) { TARDISMessage.send(p, "WORLD_RESET"); p.teleport(spawn); } if (plugin.isMVOnServer()) { plugin.getServer().dispatchCommand(plugin.getConsole(), "mv remove " + name); } if (plugin.getPM().isPluginEnabled("MultiWorld")) { plugin.getServer().dispatchCommand(plugin.getConsole(), "mw unload " + name); plugin.getServer().dispatchCommand(plugin.getConsole(), "mw delete " + name); } if (plugin.getPM().isPluginEnabled("My Worlds")) { plugin.getServer().dispatchCommand(plugin.getConsole(), "myworlds unload " + name); } if (plugin.getPM().isPluginEnabled("WorldBorder")) { // wb <world> clear plugin.getServer().dispatchCommand(plugin.getConsole(), "wb " + name + " clear"); } plugin.getServer().unloadWorld(w, true); File world_folder = new File(plugin.getServer().getWorldContainer() + File.separator + name + File.separator); if (!deleteFolder(world_folder)) { plugin.debug("Could not delete world <" + name + ">"); } } } public static boolean deleteFolder(File folder) { File[] files = folder.listFiles(); if (files != null) { //some JVMs return null for empty dirs for (File f : files) { if (f.isDirectory()) { deleteFolder(f); } else if (!f.delete()) { TARDIS.plugin.debug("Could not delete file"); } } } folder.delete(); return true; } private void removeZeroRoom(int slot, boolean hasZero) { if (slot != -1 && plugin.getConfig().getBoolean("allow.zero_room") && hasZero) { TARDISInteriorPostioning tips = new TARDISInteriorPostioning(plugin); TARDISTIPSData coords = tips.getTIPSData(slot); World w = plugin.getServer().getWorld("TARDIS_Zero_Room"); if (w != null) { tips.reclaimChunks(w, coords); } } } }