From dd2a65bef4505b31767956186568a08df4179322 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 30 Jun 2018 08:25:44 -0700 Subject: [PATCH 01/14] Moved some settings. --- src/main/java/us/tastybento/bskyblock/Settings.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/us/tastybento/bskyblock/Settings.java b/src/main/java/us/tastybento/bskyblock/Settings.java index ba9d51773..471399bf4 100644 --- a/src/main/java/us/tastybento/bskyblock/Settings.java +++ b/src/main/java/us/tastybento/bskyblock/Settings.java @@ -165,7 +165,7 @@ public class Settings implements DataObject, WorldSettings { private int islandZOffset; @ConfigComment("Island height - Lowest is 5.") - @ConfigComment("It is the y coordinate of the bedrock block in the schematic") + @ConfigComment("It is the y coordinate of the bedrock block in the schem") @ConfigEntry(path = "world.island-height") private int islandHeight = 100; @@ -428,6 +428,7 @@ public class Settings implements DataObject, WorldSettings { @ConfigEntry(path = "panel.close-on-click-outside") private boolean closePanelOnClickOutside = true; + //---------------------------------------------------------------------------------------/ private String uniqueId = "config"; // Getters and setters From 947853061e697f1694624dc348fd77700dd6c0b7 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 30 Jun 2018 10:08:16 -0700 Subject: [PATCH 02/14] Added entities to schems. --- .../bskyblock/island/builders/Clipboard.java | 47 ++++++++++++++++--- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java index 740a970f9..998acb08e 100644 --- a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java +++ b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java @@ -9,7 +9,10 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; +import java.util.Collection; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; @@ -17,6 +20,7 @@ import java.util.zip.ZipOutputStream; import org.bukkit.DyeColor; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.block.Banner; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -28,7 +32,10 @@ import org.bukkit.block.banner.PatternType; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; @@ -41,6 +48,7 @@ import org.bukkit.material.MaterialData; import org.bukkit.material.Openable; import org.bukkit.material.Redstone; import org.bukkit.material.Stairs; +import org.bukkit.util.Vector; import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.api.localization.TextVariables; @@ -133,8 +141,11 @@ public class Clipboard { user.sendMessage("commands.admin.schem.need-pos1-pos2"); return false; } + // World + World world = pos1.getWorld(); // Clear the clipboard blockConfig = new YamlConfiguration(); + int count = 0; int minX = Math.max(pos1.getBlockX(),pos2.getBlockX()); int maxX = Math.min(pos1.getBlockX(), pos2.getBlockX()); @@ -142,11 +153,15 @@ public class Clipboard { int maxY = Math.min(pos1.getBlockY(), pos2.getBlockY()); int minZ = Math.max(pos1.getBlockZ(),pos2.getBlockZ()); int maxZ = Math.min(pos1.getBlockZ(), pos2.getBlockZ()); + for (int x = Math.min(pos1.getBlockX(), pos2.getBlockX()); x <= Math.max(pos1.getBlockX(),pos2.getBlockX()); x++) { for (int y = Math.min(pos1.getBlockY(), pos2.getBlockY()); y <= Math.max(pos1.getBlockY(),pos2.getBlockY()); y++) { for (int z = Math.min(pos1.getBlockZ(), pos2.getBlockZ()); z <= Math.max(pos1.getBlockZ(),pos2.getBlockZ()); z++) { - Block block = pos1.getWorld().getBlockAt(x, y, z); - if (copyBlock(block, origin == null ? user.getLocation() : origin, copyAir)) { + Block block = world.getBlockAt(x, y, z); + if (copyBlock(block, origin == null ? user.getLocation() : origin, copyAir, world.getLivingEntities().stream() + .filter(Objects::nonNull) + .filter(e -> !(e instanceof Player) && e.getLocation().getBlock().equals(block)) + .collect(Collectors.toList()))) { minX = Math.min(minX, x); maxX = Math.max(maxX, x); minY = Math.min(minY, y); @@ -179,10 +194,9 @@ public class Clipboard { int x = location.getBlockX() + Integer.valueOf(pos[0]); int y = location.getBlockY() + Integer.valueOf(pos[1]); int z = location.getBlockZ() + Integer.valueOf(pos[2]); - Material m = Material.getMaterial(s.getString("type")); + Material m = Material.getMaterial(s.getString("type", "AIR")); Block block = location.getWorld().getBlockAt(x, y, z); if (s.getBoolean(ATTACHED)) { - plugin.log("Setting 1 tick later for " + m.toString()); plugin.getServer().getScheduler().runTask(plugin, () -> setBlock(block, s, m)); } else { setBlock(block, s, m); @@ -292,12 +306,21 @@ public class Clipboard { inv.getKeys(false).forEach(i -> ih.setItem(Integer.valueOf(i), (ItemStack)inv.get(i))); } + // Entities + if (s.isConfigurationSection("entity")) { + ConfigurationSection e = s.getConfigurationSection("entity"); + e.getKeys(false).forEach(k -> { + Location center = block.getLocation().add(new Vector(0.5, 0.0, 0.5)); + LivingEntity ent = (LivingEntity)block.getWorld().spawnEntity(center, EntityType.valueOf(e.getString(k + ".type"))); + ent.setCustomName(e.getString(k + ".name")); + }); + } } @SuppressWarnings("deprecation") - private boolean copyBlock(Block block, Location copyOrigin, boolean copyAir) { - if (!copyAir && block.getType().equals(Material.AIR)) { + private boolean copyBlock(Block block, Location copyOrigin, boolean copyAir, Collection entities) { + if (!copyAir && block.getType().equals(Material.AIR) && entities.isEmpty()) { return false; } // Create position @@ -308,6 +331,18 @@ public class Clipboard { // Position defines the section ConfigurationSection s = blockConfig.createSection(BLOCK + "." + pos); + + // Set entities + for (Entity e: entities) { + s.set("entity." + e.getUniqueId() + ".type", e.getType().name()); + s.set("entity." + e.getUniqueId() + ".name", e.getCustomName()); + } + + // Return if this is just air block + if (!copyAir && block.getType().equals(Material.AIR) && !entities.isEmpty()) { + return true; + } + // Set the block type s.set("type", block.getType().toString()); if (block.getData() != 0) { From bc39e82dd27b049a2dfdcf4cdb2dd6f76a39d954 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 1 Jul 2018 15:28:53 -0700 Subject: [PATCH 03/14] Fixed stairs orientation. --- .../bskyblock/island/builders/Clipboard.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java index 998acb08e..cfb61753f 100644 --- a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java +++ b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java @@ -246,7 +246,10 @@ public class Clipboard { if (md instanceof Directional) { Directional facing = (Directional)md; if (md instanceof Stairs) { - facing.setFacingDirection(BlockFace.valueOf(s.getString(FACING)).getOppositeFace()); + //facing.setFacingDirection(BlockFace.valueOf(s.getString(FACING)).getOppositeFace()); + Stairs stairs = (Stairs)md; + stairs.setInverted(s.getBoolean("inverted")); + stairs.setFacingDirection(BlockFace.valueOf(s.getString(FACING))); } else { facing.setFacingDirection(BlockFace.valueOf(s.getString(FACING))); } @@ -262,6 +265,8 @@ public class Clipboard { } // Block data + + if (bs instanceof Sign) { Sign sign = (Sign)bs; List lines = s.getStringList("lines"); @@ -359,8 +364,15 @@ public class Clipboard { s.set("open", open.isOpen()); } if (md instanceof Directional) { - Directional facing = (Directional)md; - s.set(FACING, facing.getFacing().name()); + if (md instanceof Stairs) { + //facing.setFacingDirection(BlockFace.valueOf(s.getString(FACING)).getOppositeFace()); + Stairs stairs = (Stairs)md; + s.set("inverted", stairs.isInverted()); + s.set(FACING, stairs.getAscendingDirection()); + } else { + Directional facing = (Directional)md; + s.set(FACING, facing.getFacing().name()); + } } if (md instanceof Attachable) { Attachable facing = (Attachable)md; From afa21d25ed89c25019ff953931aa08adf1e730d7 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 1 Jul 2018 15:47:29 -0700 Subject: [PATCH 04/14] Fixes schem issues. https://github.com/tastybento/bskyblock/issues/192 --- .../bskyblock/island/builders/Clipboard.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java index cfb61753f..02099706c 100644 --- a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java +++ b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java @@ -228,6 +228,7 @@ public class Clipboard { return; } + block.setType(m, false); BlockState bs = block.getState(); @@ -235,7 +236,6 @@ public class Clipboard { byte data = (byte)s.getInt("data"); block.setData(data); - // Material Data MaterialData md = bs.getData(); if (md instanceof Openable) { @@ -249,9 +249,9 @@ public class Clipboard { //facing.setFacingDirection(BlockFace.valueOf(s.getString(FACING)).getOppositeFace()); Stairs stairs = (Stairs)md; stairs.setInverted(s.getBoolean("inverted")); - stairs.setFacingDirection(BlockFace.valueOf(s.getString(FACING))); + stairs.setFacingDirection(BlockFace.valueOf(s.getString(FACING, "NORTH"))); } else { - facing.setFacingDirection(BlockFace.valueOf(s.getString(FACING))); + facing.setFacingDirection(BlockFace.valueOf(s.getString(FACING, "NORTH"))); } } @@ -265,8 +265,6 @@ public class Clipboard { } // Block data - - if (bs instanceof Sign) { Sign sign = (Sign)bs; List lines = s.getStringList("lines"); @@ -277,17 +275,18 @@ public class Clipboard { } if (bs instanceof Banner) { Banner banner = (Banner)bs; - DyeColor baseColor = DyeColor.valueOf(s.getString("baseColor")); + DyeColor baseColor = DyeColor.valueOf(s.getString("baseColor", "RED")); banner.setBaseColor(baseColor); int i = 0; ConfigurationSection pat = s.getConfigurationSection("pattern"); if (pat != null) { for (String pattern : pat.getKeys(false)) { - banner.setPattern(i, new Pattern(DyeColor.valueOf(pat.getString(pattern)) + banner.setPattern(i, new Pattern(DyeColor.valueOf(pat.getString(pattern, "GREEN")) , PatternType.valueOf(pattern))); i++; } } + bs.update(true, false); } if (bs instanceof CreatureSpawner) { CreatureSpawner spawner = ((CreatureSpawner) bs); @@ -299,13 +298,14 @@ public class Clipboard { spawner.setDelay(s.getInt("delay", -1)); spawner.setRequiredPlayerRange(s.getInt("requiredPlayerRange", 16)); spawner.setSpawnRange(s.getInt("spawnRange", 4)); - + bs.update(true, false); } - bs.update(true, false); + if (bs instanceof InventoryHolder) { + bs.update(true, false); Inventory ih = ((InventoryHolder)bs).getInventory(); ConfigurationSection inv = s.getConfigurationSection("inventory"); inv.getKeys(false).forEach(i -> ih.setItem(Integer.valueOf(i), (ItemStack)inv.get(i))); @@ -316,7 +316,7 @@ public class Clipboard { ConfigurationSection e = s.getConfigurationSection("entity"); e.getKeys(false).forEach(k -> { Location center = block.getLocation().add(new Vector(0.5, 0.0, 0.5)); - LivingEntity ent = (LivingEntity)block.getWorld().spawnEntity(center, EntityType.valueOf(e.getString(k + ".type"))); + LivingEntity ent = (LivingEntity)block.getWorld().spawnEntity(center, EntityType.valueOf(e.getString(k + ".type", "PIG"))); ent.setCustomName(e.getString(k + ".name")); }); } @@ -368,7 +368,7 @@ public class Clipboard { //facing.setFacingDirection(BlockFace.valueOf(s.getString(FACING)).getOppositeFace()); Stairs stairs = (Stairs)md; s.set("inverted", stairs.isInverted()); - s.set(FACING, stairs.getAscendingDirection()); + s.set(FACING, stairs.getAscendingDirection().name()); } else { Directional facing = (Directional)md; s.set(FACING, facing.getFacing().name()); From d725a3e1d8c874e165df717c7ccebf7e8857f7ae Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 2 Jul 2018 11:21:10 -0700 Subject: [PATCH 05/14] Schems: sign placeholders for names and spawn location --- .../api/localization/TextVariables.java | 3 +- .../bskyblock/database/objects/Island.java | 47 +- .../bskyblock/island/builders/Clipboard.java | 96 ++-- .../island/builders/IslandBuilder.java | 540 ++++-------------- .../island/builders/IslandBuilderNew.java | 196 ------- .../bskyblock/managers/IslandsManager.java | 11 +- .../bskyblock/managers/island/NewIsland.java | 96 ++-- .../us/tastybento/bskyblock/util/Util.java | 47 +- .../mysql/MySQLDatabaseHandlerTest.java | 23 +- .../managers/IslandsManagerTest.java | 2 +- 10 files changed, 340 insertions(+), 721 deletions(-) delete mode 100644 src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilderNew.java diff --git a/src/main/java/us/tastybento/bskyblock/api/localization/TextVariables.java b/src/main/java/us/tastybento/bskyblock/api/localization/TextVariables.java index b92ea9c3b..d0b1a4f36 100644 --- a/src/main/java/us/tastybento/bskyblock/api/localization/TextVariables.java +++ b/src/main/java/us/tastybento/bskyblock/api/localization/TextVariables.java @@ -5,7 +5,7 @@ package us.tastybento.bskyblock.api.localization; * @author Poslovitch */ public class TextVariables { - + private TextVariables() {} public static final String NAME = "[name]"; @@ -14,4 +14,5 @@ public class TextVariables { public static final String RANK = "[rank]"; public static final String LABEL = "[label]"; public static final String PERMISSION = "[permission]"; + public static final String SPAWN_HERE = "[spawn_here]"; } diff --git a/src/main/java/us/tastybento/bskyblock/database/objects/Island.java b/src/main/java/us/tastybento/bskyblock/database/objects/Island.java index 37c36667a..ab52bbebb 100755 --- a/src/main/java/us/tastybento/bskyblock/database/objects/Island.java +++ b/src/main/java/us/tastybento/bskyblock/database/objects/Island.java @@ -11,6 +11,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.World.Environment; import org.bukkit.block.BlockState; import org.bukkit.entity.Entity; import org.bukkit.util.Vector; @@ -101,7 +102,7 @@ public class Island implements DataObject { @Expose private int levelHandicap; @Expose - private Location spawnPoint; + private Map spawnPoint = new HashMap<>(); public Island() {} public Island(Location location, UUID owner, int protectionRange) { @@ -169,7 +170,7 @@ public class Island implements DataObject { return createdDate; } /** - * Gets the Island Guard flag's setting. If this is a protection flag, the this will be the + * Gets the Island Guard flag's setting. If this is a protection flag, the this will be the * rank needed to bypass this flag. If it is a Settings flag, any non-zero value means the * setting is allowed. * @param flag - flag @@ -288,10 +289,6 @@ public class Island implements DataObject { return members.getOrDefault(user.getUniqueId(), RanksManager.VISITOR_RANK); } - public Location getSpawnPoint() { - return spawnPoint; - } - /** * @param material - Material * @return count of how many tile entities of type mat are on the island at last count. Counts are done when a player places @@ -620,9 +617,21 @@ public class Island implements DataObject { //TODO default flags } - public void setSpawnPoint(Location location) { - spawnPoint = location; + /** + * Get the default spawn location for this island. Note that this may only be valid + * after the initial pasting because the player can change the island after that point + * @return the spawnPoint + */ + public Map getSpawnPoint() { + return spawnPoint; + } + /** + * Set when island is pasted + * @param spawnPoint the spawnPoint to set + */ + public void setSpawnPoint(Map spawnPoint) { + this.spawnPoint = spawnPoint; } @Override @@ -699,10 +708,10 @@ public class Island implements DataObject { members.forEach((u, i) -> { if (owner.equals(u)) { user.sendMessage("commands.admin.info.team-owner-format", "[name]", plugin.getPlayers().getName(u) - , "[rank]", user.getTranslation(plugin.getRanksManager().getRank(i))); + , "[rank]", user.getTranslation(plugin.getRanksManager().getRank(i))); } else if (i > RanksManager.VISITOR_RANK){ user.sendMessage("commands.admin.info.team-member-format", "[name]", plugin.getPlayers().getName(u) - , "[rank]", user.getTranslation(plugin.getRanksManager().getRank(i))); + , "[rank]", user.getTranslation(plugin.getRanksManager().getRank(i))); } }); } @@ -731,5 +740,23 @@ public class Island implements DataObject { } } + /** + * Set the spawn location for this island type + * @param islandType - island type + * @param l - location + */ + public void setSpawnPoint(Environment islandType, Location l) { + spawnPoint.put(islandType, l); + } + + /** + * Get the spawn point for this island type + * @param islandType - island type + * @return - location or null if one does not exist + */ + public Location getSpawnPoint(Environment islandType) { + return spawnPoint.get(islandType); + } + } \ No newline at end of file diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java index 02099706c..873583f97 100644 --- a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java +++ b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java @@ -10,7 +10,9 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; import java.util.zip.ZipEntry; @@ -82,6 +84,9 @@ public class Clipboard { private BSkyBlock plugin; private boolean copied; + // Pasted items + private Map> signs = new HashMap<>(); + private File schemFolder; public Clipboard(BSkyBlock plugin) { @@ -186,61 +191,61 @@ public class Clipboard { * @param location - location to paste */ public void paste(Location location) { + signs.clear(); blockConfig.getConfigurationSection(BLOCK).getKeys(false).forEach(b -> pasteBlock(location, blockConfig.getConfigurationSection(BLOCK + "." + b))); } - private void pasteBlock(Location location, ConfigurationSection s) { - String[] pos = s.getName().split(","); + private void pasteBlock(Location location, ConfigurationSection config) { + String[] pos = config.getName().split(","); int x = location.getBlockX() + Integer.valueOf(pos[0]); int y = location.getBlockY() + Integer.valueOf(pos[1]); int z = location.getBlockZ() + Integer.valueOf(pos[2]); - Material m = Material.getMaterial(s.getString("type", "AIR")); + // Default type is air + Material material = Material.getMaterial(config.getString("type", "AIR")); Block block = location.getWorld().getBlockAt(x, y, z); - if (s.getBoolean(ATTACHED)) { - plugin.getServer().getScheduler().runTask(plugin, () -> setBlock(block, s, m)); + if (config.getBoolean(ATTACHED)) { + plugin.getServer().getScheduler().runTask(plugin, () -> setBlock(block, config, material)); } else { - setBlock(block, s, m); + setBlock(block, config, material); } } @SuppressWarnings("deprecation") - private void setBlock(Block block, ConfigurationSection s, Material m) { + private void setBlock(Block block, ConfigurationSection config, Material material) { // Block state - if (s.getBoolean(ATTACHED) && m.toString().contains("TORCH")) { - TorchDir d = TorchDir.valueOf(s.getString(FACING)); - + if (config.getBoolean(ATTACHED) && material.toString().contains("TORCH")) { + TorchDir d = TorchDir.valueOf(config.getString(FACING)); + // The block below has to be set to something solid for this to work Block rel = block.getRelative(BlockFace.DOWN); Material rm = rel.getType(); Byte data = rel.getData(); - if (rel.isEmpty() || rel.isLiquid()) { rel.setType(Material.STONE); - block.setType(m); + block.setType(material); block.setData((byte)d.ordinal()); // Set the block back to what it was rel.setType(rm); rel.setData(data); } else { - block.setType(m); + block.setType(material); block.setData((byte)d.ordinal()); } return; } - - - block.setType(m, false); - - BlockState bs = block.getState(); - - byte data = (byte)s.getInt("data"); + // Set the block type + block.setType(material, false); + // Set the block data + byte data = (byte)config.getInt("data"); block.setData(data); + // Get the block state + BlockState bs = block.getState(); // Material Data MaterialData md = bs.getData(); if (md instanceof Openable) { Openable open = (Openable)md; - open.setOpen(s.getBoolean("open")); + open.setOpen(config.getBoolean("open")); } if (md instanceof Directional) { @@ -248,37 +253,40 @@ public class Clipboard { if (md instanceof Stairs) { //facing.setFacingDirection(BlockFace.valueOf(s.getString(FACING)).getOppositeFace()); Stairs stairs = (Stairs)md; - stairs.setInverted(s.getBoolean("inverted")); - stairs.setFacingDirection(BlockFace.valueOf(s.getString(FACING, "NORTH"))); + stairs.setInverted(config.getBoolean("inverted")); + stairs.setFacingDirection(BlockFace.valueOf(config.getString(FACING, "NORTH"))); } else { - facing.setFacingDirection(BlockFace.valueOf(s.getString(FACING, "NORTH"))); + facing.setFacingDirection(BlockFace.valueOf(config.getString(FACING, "NORTH"))); } } if (md instanceof Lever) { Lever r = (Lever)md; - r.setPowered(s.getBoolean(POWERED)); + r.setPowered(config.getBoolean(POWERED)); } if (md instanceof Button) { Button r = (Button)md; - r.setPowered(s.getBoolean(POWERED)); + r.setPowered(config.getBoolean(POWERED)); } // Block data if (bs instanceof Sign) { Sign sign = (Sign)bs; - List lines = s.getStringList("lines"); + List lines = config.getStringList("lines"); for (int i =0 ; i < lines.size(); i++) { sign.setLine(i, lines.get(i)); } sign.update(); + // Log the sign + signs.put(block.getLocation(), lines); + } if (bs instanceof Banner) { Banner banner = (Banner)bs; - DyeColor baseColor = DyeColor.valueOf(s.getString("baseColor", "RED")); + DyeColor baseColor = DyeColor.valueOf(config.getString("baseColor", "RED")); banner.setBaseColor(baseColor); int i = 0; - ConfigurationSection pat = s.getConfigurationSection("pattern"); + ConfigurationSection pat = config.getConfigurationSection("pattern"); if (pat != null) { for (String pattern : pat.getKeys(false)) { banner.setPattern(i, new Pattern(DyeColor.valueOf(pat.getString(pattern, "GREEN")) @@ -290,30 +298,27 @@ public class Clipboard { } if (bs instanceof CreatureSpawner) { CreatureSpawner spawner = ((CreatureSpawner) bs); - spawner.setSpawnedType(EntityType.valueOf(s.getString("spawnedType", "PIG"))); - spawner.setMaxNearbyEntities(s.getInt("maxNearbyEntities", 16)); - spawner.setMaxSpawnDelay(s.getInt("maxSpawnDelay", 2*60*20)); - spawner.setMinSpawnDelay(s.getInt("minSpawnDelay", 5*20)); + spawner.setSpawnedType(EntityType.valueOf(config.getString("spawnedType", "PIG"))); + spawner.setMaxNearbyEntities(config.getInt("maxNearbyEntities", 16)); + spawner.setMaxSpawnDelay(config.getInt("maxSpawnDelay", 2*60*20)); + spawner.setMinSpawnDelay(config.getInt("minSpawnDelay", 5*20)); - spawner.setDelay(s.getInt("delay", -1)); - spawner.setRequiredPlayerRange(s.getInt("requiredPlayerRange", 16)); - spawner.setSpawnRange(s.getInt("spawnRange", 4)); + spawner.setDelay(config.getInt("delay", -1)); + spawner.setRequiredPlayerRange(config.getInt("requiredPlayerRange", 16)); + spawner.setSpawnRange(config.getInt("spawnRange", 4)); bs.update(true, false); } - - - if (bs instanceof InventoryHolder) { bs.update(true, false); Inventory ih = ((InventoryHolder)bs).getInventory(); - ConfigurationSection inv = s.getConfigurationSection("inventory"); + ConfigurationSection inv = config.getConfigurationSection("inventory"); inv.getKeys(false).forEach(i -> ih.setItem(Integer.valueOf(i), (ItemStack)inv.get(i))); } // Entities - if (s.isConfigurationSection("entity")) { - ConfigurationSection e = s.getConfigurationSection("entity"); + if (config.isConfigurationSection("entity")) { + ConfigurationSection e = config.getConfigurationSection("entity"); e.getKeys(false).forEach(k -> { Location center = block.getLocation().add(new Vector(0.5, 0.0, 0.5)); LivingEntity ent = (LivingEntity)block.getWorld().spawnEntity(center, EntityType.valueOf(e.getString(k + ".type", "PIG"))); @@ -433,6 +438,13 @@ public class Clipboard { return blockConfig; } + /** + * @return the signs + */ + public Map> getSigns() { + plugin.log("DEBUG: signs " + signs.size()); + return signs; + } private void unzip(final String zipFilePath) throws IOException { Path path = Paths.get(zipFilePath); if (!(path.toFile().exists())) { diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java b/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java index 548d727e1..b158f26e4 100644 --- a/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java +++ b/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java @@ -1,61 +1,106 @@ package us.tastybento.bskyblock.island.builders; +import java.io.File; +import java.io.IOException; +import java.util.EnumMap; import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.TreeType; import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.block.BlockState; +import org.bukkit.World.Environment; import org.bukkit.block.Sign; -import org.bukkit.entity.EntityType; +import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.entity.Player; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.bukkit.material.Chest; -import us.tastybento.bskyblock.Constants; -import us.tastybento.bskyblock.Constants.GameType; +import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.api.localization.TextVariables; -import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.database.objects.Island; +import us.tastybento.bskyblock.util.Util; /** - * Fired when a team event happens. + * Generates islands * * @author tastybento * @since 1.0 */ public class IslandBuilder { - public enum IslandType { - ISLAND, - NETHER, - END - } - private Island island; private World world; - private IslandType type = IslandType.ISLAND; - private List chestItems; + private Environment type = Environment.NORMAL; private UUID playerUUID; private String playerName; + private BSkyBlock plugin; + private Map islandSchems = new EnumMap<>(Environment.class); + private Location spawnPoint; + private Runnable task; //TODO support companions? - public IslandBuilder(Island island) { + public IslandBuilder(BSkyBlock plugin, Island island) { + this.plugin = plugin; this.island = island; world = island.getWorld(); + loadIslands(); + } + + private void loadIslands() { + File schems = new File(plugin.getDataFolder(), "schems"); + if (!schems.exists()) { + if (!schems.mkdirs()) { + plugin.logError("Could not make schems folder!"); + } else { + copySchems(schems); + } + } + + try { + Clipboard cb = new Clipboard(plugin); + cb.load("island"); + islandSchems.put(Environment.NORMAL, cb); + } catch (IOException | InvalidConfigurationException e) { + plugin.logError("Could not load default island"); + } + if (plugin.getSettings().isNetherGenerate() && plugin.getSettings().isNetherIslands()) { + try { + Clipboard cbn = new Clipboard(plugin); + cbn.load("nether-island"); + islandSchems.put(Environment.NETHER, cbn); + } catch (IOException | InvalidConfigurationException e) { + plugin.logError("Could not load default nether island"); + } + } + if (plugin.getSettings().isEndGenerate() && plugin.getSettings().isEndIslands()) { + try { + Clipboard cbe = new Clipboard(plugin); + cbe.load("end-island"); + islandSchems.put(Environment.THE_END, cbe); + } catch (IOException | InvalidConfigurationException e) { + plugin.logError("Could not load default end island"); + } + } + plugin.log("Loaded " + islandSchems.size() + " islands"); + } + + /** + * Copies schems from the jar file + * @param schems2 - file containing schem + */ + private void copySchems(File schems2) { + plugin.saveResource("schems/island.schem", false); + plugin.saveResource("schems/nether-island.schem", false); + plugin.saveResource("schems/end-island.schem", false); } /** * @param type the type to set */ - public IslandBuilder setType(IslandType type) { + public IslandBuilder setType(Environment type) { this.type = type; return this; } @@ -70,417 +115,72 @@ public class IslandBuilder { } /** - * @param list the default chestItems to set + * The task to run when the island is built + * @param task + * @return IslandBuilder */ - public IslandBuilder setChestItems(List list) { - chestItems = list; + public IslandBuilder run(Runnable task) { + this.task = task; return this; } public void build() { + plugin.log("Pasting island to " + type); + Location loc = island.getCenter(); // Switch on island type switch (type) { - case ISLAND: - world = island.getWorld(); - if (Constants.GAMETYPE == GameType.ACIDISLAND) { - generateAcidIslandBlocks(); - } else { - generateIslandBlocks(); - } - break; - case NETHER: - world = Bukkit.getWorld(island.getWorld().getName() + "_nether"); - if (world == null) { - return; - } - generateNetherBlocks(); - break; - case END: - world = Bukkit.getWorld(island.getWorld().getName() + "_the_end"); - if (world == null) { - return; - } - generateEndBlocks(); - break; + case NETHER: + world = Bukkit.getWorld(island.getWorld().getName() + "_nether"); + if (world == null) { + return; + } + loc = island.getCenter().toVector().toLocation(world); + break; + case THE_END: + world = Bukkit.getWorld(island.getWorld().getName() + "_the_end"); + if (world == null) { + return; + } + loc = island.getCenter().toVector().toLocation(world); + break; + default: + break; } + islandSchems.get(type).paste(loc); // Do other stuff + // Handle signs - signs are attachable, so they are not there until 1 tick after pasting + if (playerUUID != null) { + Bukkit.getScheduler().runTaskLater(plugin, () -> islandSchems.get(type).getSigns().forEach(this::writeSign), 2L); + } + if (task != null) { + Bukkit.getScheduler().runTaskLater(plugin, task, 3L); + } + } + + private void writeSign(Location loc, List lines) { + Sign sign = (Sign) loc.getBlock().getState(); + org.bukkit.material.Sign s = (org.bukkit.material.Sign) sign.getData(); + lines.forEach(plugin::log); + // Handle spawn sign + if (!lines.isEmpty() && lines.get(0).equalsIgnoreCase(TextVariables.SPAWN_HERE)) { + loc.getBlock().setType(Material.AIR); + // Orient to face same direction as sign + spawnPoint = new Location(loc.getWorld(), loc.getBlockX() + 0.5D, loc.getBlockY(), + loc.getBlockZ() + 0.5D, Util.blockFaceToFloat(s.getFacing().getOppositeFace()), 30F); + return; + } + // Sub in player's name + for (int i = 0 ; i < lines.size(); i++) { + sign.setLine(i, lines.get(i).replace(TextVariables.NAME, playerName)); + } + sign.update(); } /** - * Creates the AcidIsland default island block by block + * @return the spawnPoint */ - private void generateAcidIslandBlocks() { - // AcidIsland - // Build island layer by layer - // Start from the base - // half sandstone; half sand - int x = island.getCenter().getBlockX(); - int z = island.getCenter().getBlockZ(); - int islandHeight = island.getCenter().getBlockY(); - - int y = 0; - for (int x_space = x - 4; x_space <= x + 4; x_space++) { - for (int z_space = z - 4; z_space <= z + 4; z_space++) { - Block b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.BEDROCK); - } - } - for (y = 1; y < islandHeight + 5; y++) { - for (int x_space = x - 4; x_space <= x + 4; x_space++) { - for (int z_space = z - 4; z_space <= z + 4; z_space++) { - Block b = world.getBlockAt(x_space, y, z_space); - if (y < (islandHeight / 2)) { - b.setType(Material.SANDSTONE); - } else { - b.setType(Material.SAND); - } - } - } - } - // Then cut off the corners to make it round-ish - for (y = 0; y < islandHeight + 5; y++) { - for (int x_space = x - 4; x_space <= x + 4; x_space += 8) { - for (int z_space = z - 4; z_space <= z + 4; z_space += 8) { - Block b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.STATIONARY_WATER); - } - } - } - // Add some grass - for (y = islandHeight + 4; y < islandHeight + 5; y++) { - for (int x_space = x - 2; x_space <= x + 2; x_space++) { - for (int z_space = z - 2; z_space <= z + 2; z_space++) { - Block blockToChange = world.getBlockAt(x_space, y, z_space); - blockToChange.setType(Material.GRASS); - } - } - } - // Place bedrock - MUST be there (ensures island are not - // overwritten - Block b = world.getBlockAt(x, islandHeight, z); - b.setType(Material.BEDROCK); - // Then add some more dirt in the classic shape - y = islandHeight + 3; - for (int x_space = x - 2; x_space <= x + 2; x_space++) { - for (int z_space = z - 2; z_space <= z + 2; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.DIRT); - } - } - b = world.getBlockAt(x - 3, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x + 3, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z - 3); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z + 3); - b.setType(Material.DIRT); - y = islandHeight + 2; - for (int x_space = x - 1; x_space <= x + 1; x_space++) { - for (int z_space = z - 1; z_space <= z + 1; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.DIRT); - } - } - b = world.getBlockAt(x - 2, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x + 2, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z - 2); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z + 2); - b.setType(Material.DIRT); - y = islandHeight + 1; - b = world.getBlockAt(x - 1, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x + 1, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z - 1); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z + 1); - b.setType(Material.DIRT); - - // Add island items - y = islandHeight; - // Add tree (natural) - Location treeLoc = new Location(world, x, y + 5D, z); - world.generateTree(treeLoc, TreeType.ACACIA); - - // Place a helpful sign in front of player - placeSign(x, islandHeight + 5, z + 3); - // Place the chest - no need to use the safe spawn function - // because we - // know what this island looks like - placeChest(x, islandHeight + 5, z + 1); - } - - private void generateIslandBlocks() { - // Skyblock - // Build island layer by layer - // Start from the base - // half sandstone; half sand - int x = island.getCenter().getBlockX(); - int z = island.getCenter().getBlockZ(); - int islandHeight = island.getCenter().getBlockY(); - - World world = island.getCenter().getWorld(); - int y; - // Add some grass - for (y = islandHeight + 4; y < islandHeight + 5; y++) { - for (int x_space = x - 3; x_space <= x + 3; x_space++) { - for (int z_space = z - 3; z_space <= z + 3; z_space++) { - world.getBlockAt(x_space, y, z_space).setType(Material.GRASS); - } - } - } - - // Then cut off the corners to make it round-ish - for (int x_space = x - 3; x_space <= x + 3; x_space += 6) { - for (int z_space = z - 3; z_space <= z + 3; z_space += 6) { - world.getBlockAt(x_space, y-1, z_space).setType(Material.AIR); - } - } - // Place bedrock - MUST be there (ensures island are not - // overwritten - Block b = world.getBlockAt(x, islandHeight, z); - b.setType(Material.BEDROCK); - // Then add some more dirt in the classic shape - y = islandHeight + 3; - for (int x_space = x - 2; x_space <= x + 2; x_space++) { - for (int z_space = z - 2; z_space <= z + 2; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.DIRT); - } - } - b = world.getBlockAt(x - 3, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x + 3, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z - 3); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z + 3); - b.setType(Material.DIRT); - y = islandHeight + 2; - for (int x_space = x - 1; x_space <= x + 1; x_space++) { - for (int z_space = z - 1; z_space <= z + 1; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.DIRT); - } - } - b = world.getBlockAt(x - 2, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x + 2, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z - 2); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z + 2); - b.setType(Material.DIRT); - y = islandHeight + 1; - b = world.getBlockAt(x - 1, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x + 1, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z - 1); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z + 1); - b.setType(Material.DIRT); - - // Add island items - y = islandHeight; - // Add tree (natural) - Location treeLoc = new Location(world, x, y + 5D, z); - world.generateTree(treeLoc, TreeType.TREE); - - // Place a helpful sign in front of player - placeSign(x, islandHeight + 5, z + 3); - // Place the chest - no need to use the safe spawn function - // because we - // know what this island looks like - placeChest(x, islandHeight + 5, z + 1); - } - - private void generateNetherBlocks() { - // Nether block - int x = island.getCenter().getBlockX(); - int z = island.getCenter().getBlockZ(); - int islandHeight = island.getCenter().getBlockY(); - - int y; - for (y = islandHeight + 4; y < islandHeight + 5; y++) { - for (int x_space = x - 3; x_space <= x + 3; x_space++) { - for (int z_space = z - 3; z_space <= z + 3; z_space++) { - world.getBlockAt(x_space, y, z_space).setType(Material.NETHER_BRICK); - } - } - } - // Then cut off the corners to make it round-ish - for (int x_space = x - 3; x_space <= x + 3; x_space += 6) { - for (int z_space = z - 3; z_space <= z + 3; z_space += 6) { - world.getBlockAt(x_space, y-1, z_space).setType(Material.AIR); - } - } - // Place bedrock - MUST be there (ensures island are not - // overwritten - Block b = world.getBlockAt(x, islandHeight, z); - b.setType(Material.BEDROCK); - // Then add some more dirt in the classic shape - y = islandHeight + 3; - for (int x_space = x - 2; x_space <= x + 2; x_space++) { - for (int z_space = z - 2; z_space <= z + 2; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.NETHERRACK); - } - } - b = world.getBlockAt(x - 3, y, z); - b.setType(Material.SOUL_SAND); - b = world.getBlockAt(x + 3, y, z); - b.setType(Material.SOUL_SAND); - b = world.getBlockAt(x, y, z - 3); - b.setType(Material.SOUL_SAND); - b = world.getBlockAt(x, y, z + 3); - b.setType(Material.SOUL_SAND); - y = islandHeight + 2; - for (int x_space = x - 1; x_space <= x + 1; x_space++) { - for (int z_space = z - 1; z_space <= z + 1; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.GRAVEL); - } - } - b = world.getBlockAt(x - 2, y, z); - b.setType(Material.QUARTZ_ORE); - b = world.getBlockAt(x + 2, y, z); - b.setType(Material.QUARTZ_ORE); - b = world.getBlockAt(x, y, z - 2); - b.setType(Material.QUARTZ_ORE); - b = world.getBlockAt(x, y, z + 2); - b.setType(Material.QUARTZ_ORE); - y = islandHeight + 1; - b = world.getBlockAt(x - 1, y, z); - b.setType(Material.MAGMA); - b = world.getBlockAt(x + 1, y, z); - b.setType(Material.MAGMA); - b = world.getBlockAt(x, y, z - 1); - b.setType(Material.MAGMA); - b = world.getBlockAt(x, y, z + 1); - b.setType(Material.MAGMA); - - // Place a helpful sign in front of player - placeSign(x, islandHeight + 5, z + 3); - // Place the chest - no need to use the safe spawn function - // because we know what this island looks like - placeChest(x, islandHeight + 5, z + 1); - } - - private void generateEndBlocks() { - // Nether block - int x = island.getCenter().getBlockX(); - int z = island.getCenter().getBlockZ(); - int islandHeight = island.getCenter().getBlockY(); - - int y; - // Add some grass - for (y = islandHeight + 4; y < islandHeight + 5; y++) { - for (int x_space = x - 3; x_space <= x + 3; x_space++) { - for (int z_space = z - 3; z_space <= z + 3; z_space++) { - world.getBlockAt(x_space, y, z_space).setType(Material.END_BRICKS); - } - } - } - // Then cut off the corners to make it round-ish - for (int x_space = x - 3; x_space <= x + 3; x_space += 6) { - for (int z_space = z - 3; z_space <= z + 3; z_space += 6) { - world.getBlockAt(x_space, y-1, z_space).setType(Material.AIR); - } - } - // Place bedrock - MUST be there (ensures island are not - // overwritten - Block b = world.getBlockAt(x, islandHeight, z); - b.setType(Material.BEDROCK); - // Then add some more dirt in the classic shape - y = islandHeight + 3; - for (int x_space = x - 2; x_space <= x + 2; x_space++) { - for (int z_space = z - 2; z_space <= z + 2; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.ENDER_STONE); - } - } - b = world.getBlockAt(x - 3, y, z); - b.setType(Material.OBSIDIAN); - b = world.getBlockAt(x + 3, y, z); - b.setType(Material.OBSIDIAN); - b = world.getBlockAt(x, y, z - 3); - b.setType(Material.OBSIDIAN); - b = world.getBlockAt(x, y, z + 3); - b.setType(Material.OBSIDIAN); - y = islandHeight + 2; - for (int x_space = x - 1; x_space <= x + 1; x_space++) { - for (int z_space = z - 1; z_space <= z + 1; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.ENDER_STONE); - } - } - b = world.getBlockAt(x - 2, y, z); - b.setType(Material.ENDER_STONE); - b = world.getBlockAt(x + 2, y, z); - b.setType(Material.ENDER_STONE); - b = world.getBlockAt(x, y, z - 2); - b.setType(Material.ENDER_STONE); - b = world.getBlockAt(x, y, z + 2); - b.setType(Material.ENDER_STONE); - y = islandHeight + 1; - b = world.getBlockAt(x - 1, y, z); - b.setType(Material.ENDER_STONE); - b = world.getBlockAt(x + 1, y, z); - b.setType(Material.ENDER_STONE); - b = world.getBlockAt(x, y, z - 1); - b.setType(Material.ENDER_STONE); - b = world.getBlockAt(x, y, z + 1); - b.setType(Material.ENDER_STONE); - - // Add island items - y = islandHeight; - // Spawn an ender crystal - world.spawnEntity(new Location(world, x, y + 5D, z), EntityType.ENDER_CRYSTAL); - - // Place a helpful sign in front of player - placeSign(x, islandHeight + 5, z + 3); - // Place the chest - no need to use the safe spawn function - // because we know what this island looks like - placeChest(x, islandHeight + 5, z + 1); - } - - private void placeSign(int x, int y, int z) { - Block blockToChange = world.getBlockAt(x, y, z); - blockToChange.setType(Material.SIGN_POST); - if (playerUUID != null) { - Sign sign = (Sign) blockToChange.getState(); - User user = User.getInstance(playerUUID); - - // Sets the lines of the sign - sign.setLine(0, user.getTranslation("new-island.sign.line0", TextVariables.NAME, playerName)); - sign.setLine(1, user.getTranslation("new-island.sign.line1", TextVariables.NAME, playerName)); - sign.setLine(2, user.getTranslation("new-island.sign.line2", TextVariables.NAME, playerName)); - sign.setLine(3, user.getTranslation("new-island.sign.line3", TextVariables.NAME, playerName)); - - ((org.bukkit.material.Sign) sign.getData()).setFacingDirection(BlockFace.NORTH); - sign.update(); - } - } - - private void placeChest(int x, int y, int z) { - // Fill the chest and orient it correctly - Block blockToChange = world.getBlockAt(x, y, z); - blockToChange.setType(Material.CHEST); - BlockState state = blockToChange.getState(); - Chest chest = new Chest(BlockFace.SOUTH); - state.setData(chest); - state.update(); - if (!chestItems.isEmpty()) { - InventoryHolder chestBlock = (InventoryHolder) state; - for (ItemStack item: chestItems) { - chestBlock.getInventory().addItem(item); - } - } + public Optional getSpawnPoint() { + return Optional.ofNullable(spawnPoint); } } diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilderNew.java b/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilderNew.java deleted file mode 100644 index 626a32ad2..000000000 --- a/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilderNew.java +++ /dev/null @@ -1,196 +0,0 @@ -package us.tastybento.bskyblock.island.builders; - -import java.io.File; -import java.io.IOException; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.entity.Player; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.bukkit.material.Chest; - -import us.tastybento.bskyblock.BSkyBlock; -import us.tastybento.bskyblock.api.localization.TextVariables; -import us.tastybento.bskyblock.api.user.User; -import us.tastybento.bskyblock.database.objects.Island; - -/** - * Generates islands - * - * @author tastybento - * @since 1.0 - */ -public class IslandBuilderNew { - - public enum IslandType { - ISLAND, - NETHER, - END - } - - private Island island; - private World world; - private IslandType type = IslandType.ISLAND; - private List chestItems; - private UUID playerUUID; - private String playerName; - private BSkyBlock plugin; - private Map islandSchems = new EnumMap<>(IslandType.class); - - //TODO support companions? - - public IslandBuilderNew(BSkyBlock plugin, Island island) { - this.plugin = plugin; - this.island = island; - world = island.getWorld(); - loadIslands(); - } - - private void loadIslands() { - File schems = new File(plugin.getDataFolder(), "schems"); - if (!schems.exists()) { - if (!schems.mkdirs()) { - plugin.logError("Could not make schems folder!"); - } else { - copySchems(schems); - } - } - - try { - Clipboard cb = new Clipboard(plugin); - cb.load("island"); - islandSchems.put(IslandType.ISLAND, cb); - } catch (IOException | InvalidConfigurationException e) { - plugin.logError("Could not load default island"); - } - if (plugin.getSettings().isNetherGenerate() && plugin.getSettings().isNetherIslands()) { - try { - Clipboard cbn = new Clipboard(plugin); - cbn.load("nether-island"); - islandSchems.put(IslandType.NETHER, cbn); - } catch (IOException | InvalidConfigurationException e) { - plugin.logError("Could not load default nether island"); - } - } - if (plugin.getSettings().isEndGenerate() && plugin.getSettings().isEndIslands()) { - try { - Clipboard cbe = new Clipboard(plugin); - cbe.load("end-island"); - islandSchems.put(IslandType.END, cbe); - } catch (IOException | InvalidConfigurationException e) { - plugin.logError("Could not load default end island"); - } - } - plugin.log("Loaded " + islandSchems.size() + " islands"); - } - - /** - * Copies schems from the jar file - * @param schems2 - file containing schem - */ - private void copySchems(File schems2) { - plugin.saveResource("schems/island.schem", false); - plugin.saveResource("schems/nether-island.schem", false); - plugin.saveResource("schems/end-island.schem", false); - } - - /** - * @param type the type to set - */ - public IslandBuilderNew setType(IslandType type) { - this.type = type; - return this; - } - - /** - * @param player - the player the player to set - */ - public IslandBuilderNew setPlayer(Player player) { - playerUUID = player.getUniqueId(); - playerName = player.getName(); - return this; - } - - /** - * @param list the default chestItems to set - */ - public IslandBuilderNew setChestItems(List list) { - chestItems = list; - return this; - } - - public void build() { - plugin.log("Pasting island to " + type); - Location loc = island.getCenter(); - // Switch on island type - switch (type) { - case NETHER: - world = Bukkit.getWorld(island.getWorld().getName() + "_nether"); - if (world == null) { - return; - } - loc = island.getCenter().toVector().toLocation(world); - break; - case END: - world = Bukkit.getWorld(island.getWorld().getName() + "_the_end"); - if (world == null) { - return; - } - loc = island.getCenter().toVector().toLocation(world); - break; - default: - break; - } - plugin.log("Pasting island to " + loc); - islandSchems.get(type).paste(loc); - // Do other stuff - } - - private void placeSign(int x, int y, int z) { - Block blockToChange = world.getBlockAt(x, y, z); - blockToChange.setType(Material.SIGN_POST); - if (playerUUID != null) { - Sign sign = (Sign) blockToChange.getState(); - User user = User.getInstance(playerUUID); - - // Sets the lines of the sign - sign.setLine(0, user.getTranslation("new-island.sign.line0", TextVariables.NAME, playerName)); - sign.setLine(1, user.getTranslation("new-island.sign.line1", TextVariables.NAME, playerName)); - sign.setLine(2, user.getTranslation("new-island.sign.line2", TextVariables.NAME, playerName)); - sign.setLine(3, user.getTranslation("new-island.sign.line3", TextVariables.NAME, playerName)); - - ((org.bukkit.material.Sign) sign.getData()).setFacingDirection(BlockFace.NORTH); - sign.update(); - } - } - - private void placeChest(int x, int y, int z) { - // Fill the chest and orient it correctly - Block blockToChange = world.getBlockAt(x, y, z); - blockToChange.setType(Material.CHEST); - BlockState state = blockToChange.getState(); - Chest chest = new Chest(BlockFace.SOUTH); - state.setData(chest); - state.update(); - if (!chestItems.isEmpty()) { - InventoryHolder chestBlock = (InventoryHolder) state; - for (ItemStack item: chestItems) { - chestBlock.getInventory().addItem(item); - } - } - } -} - - diff --git a/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java b/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java index 626de2ba6..b8996b3ec 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java +++ b/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java @@ -348,6 +348,7 @@ public class IslandsManager { public Location getSafeHomeLocation(World world, User user, int number) { // Try the numbered home location first Location l = plugin.getPlayers().getHomeLocation(world, user, number); + if (l == null) { // Get the default home, which may be null too, but that's okay number = 1; @@ -433,7 +434,7 @@ public class IslandsManager { * @return the spawnPoint or null if spawn does not exist */ public Location getSpawnPoint(World world) { - return spawn.containsKey(world) ? spawn.get(world).getSpawnPoint() : null; + return spawn.containsKey(world) ? spawn.get(world).getSpawnPoint(world.getEnvironment()) : null; } /** @@ -480,7 +481,7 @@ public class IslandsManager { /** * Teleport player to a home location. If one cannot be found a search is done to * find a safe place. - * + * * @param world - world to check * @param player - the player * @param number - a number - home location to do to @@ -504,7 +505,7 @@ public class IslandsManager { /** * Teleport player to a home location. If one cannot be found a search is done to * find a safe place. - * + * * @param world - world to check * @param player - the player * @param number - a number - home location to do to @@ -548,7 +549,7 @@ public class IslandsManager { // If this is a new island, then run commands and do resets if (newIsland) { // TODO add command running - + // Remove money inventory etc. if (plugin.getIWM().isOnJoinResetEnderChest(world)) { user.getPlayer().getEnderChest().clear(); @@ -723,7 +724,7 @@ public class IslandsManager { // Move player to spawn if (spawn.containsKey(island.getWorld())) { // go to island spawn - player.teleport(spawn.get(island.getWorld()).getSpawnPoint()); + player.teleport(spawn.get(island.getWorld()).getSpawnPoint(island.getWorld().getEnvironment())); } else { if (!player.performCommand(Constants.SPAWNCOMMAND)) { plugin.logWarning("During island deletion player " + player.getName() + " could not be sent to spawn so was dropped, sorry."); diff --git a/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java b/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java index 2f1953b5d..ec13941b0 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java +++ b/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java @@ -4,6 +4,7 @@ import java.io.IOException; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.World.Environment; import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.api.events.IslandBaseEvent; @@ -11,7 +12,7 @@ import us.tastybento.bskyblock.api.events.island.IslandEvent; import us.tastybento.bskyblock.api.events.island.IslandEvent.Reason; import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.database.objects.Island; -import us.tastybento.bskyblock.island.builders.IslandBuilderNew; +import us.tastybento.bskyblock.island.builders.IslandBuilder; /** * Create and paste a new island @@ -117,40 +118,67 @@ public class NewIsland { .island(island) .location(island.getCenter()) .build(); - if (!event.isCancelled()) { - // Create island - IslandBuilderNew ib = new IslandBuilderNew(plugin, island) - .setPlayer(user.getPlayer()) - .setChestItems(plugin.getSettings().getChestItems()) - .setType(IslandBuilderNew.IslandType.ISLAND); - ib.build(); - if (plugin.getSettings().isNetherGenerate() && plugin.getSettings().isNetherIslands() && plugin.getIWM().getNetherWorld() != null) { - ib.setType(IslandBuilderNew.IslandType.NETHER).build(); - } - if (plugin.getSettings().isEndGenerate() && plugin.getSettings().isEndIslands() && plugin.getIWM().getEndWorld() != null) { - ib.setType(IslandBuilderNew.IslandType.END).build(); - } - // Teleport player to their island - plugin.getIslands().homeTeleport(world, user.getPlayer(), true); - // Fire exit event - Reason reasonDone = Reason.CREATED; - switch (reason) { - case CREATE: - reasonDone = Reason.CREATED; - break; - case RESET: - reasonDone = Reason.RESETTED; - break; - default: - break; - } - IslandEvent.builder() - .involvedPlayer(user.getUniqueId()) - .reason(reasonDone) - .island(island) - .location(island.getCenter()) - .build(); + if (event.isCancelled()) { + return; } + // Create island + IslandBuilder ib = new IslandBuilder(plugin, island) + .setPlayer(user.getPlayer()) + .setType(Environment.NORMAL); + ib.run(() -> { + // Set initial spawn point if one exists + ib.getSpawnPoint().ifPresent(l -> { + plugin.getPlayers().setHomeLocation(user, l, 1); + island.setSpawnPoint(Environment.NORMAL, l); + }); + // Teleport player after this island is built + plugin.getIslands().homeTeleport(world, user.getPlayer(), true); + }); + // Build it + ib.build(); + + // Make nether island + if (plugin.getSettings().isNetherGenerate() && plugin.getSettings().isNetherIslands() && plugin.getIWM().getNetherWorld() != null) { + IslandBuilder ib_nether = new IslandBuilder(plugin, island) + .setPlayer(user.getPlayer()) + .setType(Environment.NETHER); + ib_nether.run(() -> ib_nether.getSpawnPoint().ifPresent(l -> island.setSpawnPoint(Environment.NETHER, l))); + // Build it + ib_nether.build(); + } + + // Make end island + if (plugin.getSettings().isEndGenerate() && plugin.getSettings().isEndIslands() && plugin.getIWM().getEndWorld() != null) { + IslandBuilder ib_end = new IslandBuilder(plugin, island) + .setPlayer(user.getPlayer()) + .setType(Environment.THE_END); + ib_end.run(() -> { + // Set initial spawn point if one exists + ib_end.getSpawnPoint().ifPresent(l -> island.setSpawnPoint(Environment.NETHER, l)); + }); + // Build it + ib_end.build(); + } + + // Fire exit event + Reason reasonDone = Reason.CREATED; + switch (reason) { + case CREATE: + reasonDone = Reason.CREATED; + break; + case RESET: + reasonDone = Reason.RESETTED; + break; + default: + break; + } + IslandEvent.builder() + .involvedPlayer(user.getUniqueId()) + .reason(reasonDone) + .island(island) + .location(island.getCenter()) + .build(); + } /** diff --git a/src/main/java/us/tastybento/bskyblock/util/Util.java b/src/main/java/us/tastybento/bskyblock/util/Util.java index 00d79c5b4..9e12b9b43 100755 --- a/src/main/java/us/tastybento/bskyblock/util/Util.java +++ b/src/main/java/us/tastybento/bskyblock/util/Util.java @@ -13,6 +13,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.World.Environment; +import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.util.Vector; @@ -243,5 +244,49 @@ public class Util { return world.getEnvironment().equals(Environment.NORMAL) ? world : Bukkit.getWorld(world.getName().replaceAll(NETHER, "").replaceAll(THE_END, "")); } - + /** + * Converts block face direction to radial degrees. Returns 0 if block face + * is not radial. + * + * @param face + * @return degrees + */ + public static float blockFaceToFloat(BlockFace face) { + switch (face) { + case EAST: + return 90F; + case EAST_NORTH_EAST: + return 67.5F; + case EAST_SOUTH_EAST: + return 0F; + case NORTH: + return 0F; + case NORTH_EAST: + return 45F; + case NORTH_NORTH_EAST: + return 22.5F; + case NORTH_NORTH_WEST: + return 337.5F; + case NORTH_WEST: + return 315F; + case SOUTH: + return 180F; + case SOUTH_EAST: + return 135F; + case SOUTH_SOUTH_EAST: + return 157.5F; + case SOUTH_SOUTH_WEST: + return 202.5F; + case SOUTH_WEST: + return 225F; + case WEST: + return 270F; + case WEST_NORTH_WEST: + return 292.5F; + case WEST_SOUTH_WEST: + return 247.5F; + default: + return 0F; + } + } } diff --git a/src/test/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandlerTest.java b/src/test/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandlerTest.java index 8eda4b1cf..9b1d8552a 100644 --- a/src/test/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandlerTest.java +++ b/src/test/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandlerTest.java @@ -16,6 +16,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Server; import org.bukkit.World; +import org.bukkit.World.Environment; import org.bukkit.inventory.ItemFactory; import org.bukkit.plugin.PluginManager; import org.junit.BeforeClass; @@ -39,7 +40,7 @@ import us.tastybento.bskyblock.util.Util; @RunWith(PowerMockRunner.class) @PrepareForTest( { BSkyBlock.class, Util.class }) public class MySQLDatabaseHandlerTest { - + private static MySQLDatabaseHandler handler; private static Island instance; private static String UNIQUE_ID = "xyz"; @@ -66,14 +67,14 @@ public class MySQLDatabaseHandlerTest { Bukkit.setServer(server); when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger()); - + Whitebox.setInternalState(BSkyBlock.class, "instance", plugin); - + Settings settings = mock(Settings.class); - + when(plugin.getSettings()).thenReturn(settings); when(settings.getDeathsMax()).thenReturn(10); - + when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger()); dbConn = mock(MySQLDatabaseConnecter.class); Connection connection = mock(Connection.class); @@ -88,7 +89,7 @@ public class MySQLDatabaseHandlerTest { instance = new Island(); instance.setUniqueId(UNIQUE_ID); handler = new MySQLDatabaseHandler<>(plugin, Island.class, dbConn); - + PowerMockito.mockStatic(Util.class); when(Util.sameWorld(Mockito.any(), Mockito.any())).thenReturn(true); @@ -120,11 +121,11 @@ public class MySQLDatabaseHandlerTest { players.setPlayerName("name"); players.setPlayerUUID(UUID.randomUUID()); players.setResetsLeft(3); - + MySQLDatabaseHandler h = new MySQLDatabaseHandler<>(plugin, Players.class, dbConn); h.saveObject(players); - + Island island = new Island(); island.setUniqueId(UNIQUE_ID); island.setCenter(location); @@ -149,12 +150,12 @@ public class MySQLDatabaseHandlerTest { island.setPurgeProtected(true); island.setRange(100); island.setSpawn(true); - island.setSpawnPoint(location); + island.setSpawnPoint(Environment.NORMAL, location); island.setWorld(world); - + MySQLDatabaseHandler ih = new MySQLDatabaseHandler<>(plugin, Island.class, dbConn); ih.saveObject(island); - + } } diff --git a/src/test/java/us/tastybento/bskyblock/managers/IslandsManagerTest.java b/src/test/java/us/tastybento/bskyblock/managers/IslandsManagerTest.java index 9944d464f..57dd5e939 100644 --- a/src/test/java/us/tastybento/bskyblock/managers/IslandsManagerTest.java +++ b/src/test/java/us/tastybento/bskyblock/managers/IslandsManagerTest.java @@ -600,7 +600,7 @@ public class IslandsManagerTest { Island island = mock(Island.class); when(island.getWorld()).thenReturn(world); // Make a spawn position on the island - when(island.getSpawnPoint()).thenReturn(location); + when(island.getSpawnPoint(Mockito.any())).thenReturn(location); // Set the spawn island im.setSpawn(island); assertEquals(location,im.getSpawnPoint(world)); From c430d910b271b8066c4717628f6a2ea7ee07563f Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 2 Jul 2018 18:51:18 -0700 Subject: [PATCH 06/14] Added SchemsManager to handle global schems --- .../us/tastybento/bskyblock/BSkyBlock.java | 37 +++- .../us/tastybento/bskyblock/Settings.java | 8 + .../bskyblock/api/addons/Addon.java | 12 ++ .../api/configuration/WorldSettings.java | 18 +- .../commands/admin/AdminSchemCommand.java | 6 +- .../bskyblock/island/builders/Clipboard.java | 175 +++++++++++++----- .../island/builders/IslandBuilder.java | 117 +----------- .../managers/IslandWorldManager.java | 32 +++- .../bskyblock/managers/SchemsManager.java | 105 +++++++++++ .../bskyblock/managers/island/NewIsland.java | 34 +--- 10 files changed, 337 insertions(+), 207 deletions(-) create mode 100644 src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java diff --git a/src/main/java/us/tastybento/bskyblock/BSkyBlock.java b/src/main/java/us/tastybento/bskyblock/BSkyBlock.java index 7cac0f642..e9d4616ed 100755 --- a/src/main/java/us/tastybento/bskyblock/BSkyBlock.java +++ b/src/main/java/us/tastybento/bskyblock/BSkyBlock.java @@ -25,6 +25,7 @@ import us.tastybento.bskyblock.managers.IslandsManager; import us.tastybento.bskyblock.managers.LocalesManager; import us.tastybento.bskyblock.managers.PlayersManager; import us.tastybento.bskyblock.managers.RanksManager; +import us.tastybento.bskyblock.managers.SchemsManager; import us.tastybento.bskyblock.util.HeadGetter; /** @@ -50,6 +51,7 @@ public class BSkyBlock extends JavaPlugin { private FlagsManager flagsManager; private IslandWorldManager islandWorldManager; private RanksManager ranksManager; + private SchemsManager schemsManager; // Settings private Settings settings; @@ -78,7 +80,7 @@ public class BSkyBlock extends JavaPlugin { // Start head getter headGetter = new HeadGetter(this); - + // Load metrics metrics = new Metrics(instance); registerCustomCharts(); @@ -95,21 +97,26 @@ public class BSkyBlock extends JavaPlugin { getServer().getScheduler().runTask(this, () -> { // Create the world if it does not exist islandWorldManager = new IslandWorldManager(instance); - + // Load schems manager + schemsManager = new SchemsManager(instance); + // Load the default island schems + schemsManager.loadIslands(getIWM().getIslandWorld()); + // Set up commands new IslandCommand(); new AdminCommand(); - + // Locales manager must be loaded before addons localesManager = new LocalesManager(instance); PlaceholderHandler.register(instance); - + // Load addons. Addons may load worlds, so they must go before islands are loaded. addonsManager = new AddonsManager(instance); addonsManager.loadAddons(); // Enable addons addonsManager.enableAddons(); - + + getServer().getScheduler().runTask(instance, () -> { // Load Flags flagsManager = new FlagsManager(instance); @@ -119,9 +126,9 @@ public class BSkyBlock extends JavaPlugin { // Load islands from database - need to wait until all the worlds are loaded islandsManager.load(); - + // Save islands & players data asynchronously every X minutes - + instance.getServer().getScheduler().runTaskTimer(instance, () -> { playersManager.save(true); islandsManager.save(true); @@ -295,15 +302,15 @@ public class BSkyBlock extends JavaPlugin { public HeadGetter getHeadGetter() { return headGetter; } - + public void log(String string) { getLogger().info(() -> string); } - + public void logError(String error) { getLogger().severe(() -> error); } - + public void logWarning(String warning) { getLogger().warning(warning); } @@ -317,4 +324,14 @@ public class BSkyBlock extends JavaPlugin { islandWorldManager.addWorld(world, worldSettings); } + + + /** + * @return the schemsManager + */ + public SchemsManager getSchemsManager() { + return schemsManager; + } + + } diff --git a/src/main/java/us/tastybento/bskyblock/Settings.java b/src/main/java/us/tastybento/bskyblock/Settings.java index 471399bf4..fcc9649dc 100644 --- a/src/main/java/us/tastybento/bskyblock/Settings.java +++ b/src/main/java/us/tastybento/bskyblock/Settings.java @@ -6,12 +6,14 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.bukkit.GameMode; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; +import us.tastybento.bskyblock.api.addons.Addon; import us.tastybento.bskyblock.api.configuration.ConfigComment; import us.tastybento.bskyblock.api.configuration.ConfigEntry; import us.tastybento.bskyblock.api.configuration.StoreAt; @@ -1563,5 +1565,11 @@ public class Settings implements DataObject, WorldSettings { this.onLeaveResetEnderChest = onLeaveResetEnderChest; } + @Override + public Optional getAddon() { + // This is a plugin, not an addon + return Optional.empty(); + } + } \ No newline at end of file diff --git a/src/main/java/us/tastybento/bskyblock/api/addons/Addon.java b/src/main/java/us/tastybento/bskyblock/api/addons/Addon.java index dddb3ed06..9a88e2cdf 100644 --- a/src/main/java/us/tastybento/bskyblock/api/addons/Addon.java +++ b/src/main/java/us/tastybento/bskyblock/api/addons/Addon.java @@ -282,4 +282,16 @@ public abstract class Addon implements AddonInterface { public Optional getAddonByName(String name) { return getBSkyBlock().getAddonsManager().getAddonByName(name); } + + public void log(String string) { + getBSkyBlock().log(string); + } + + public void logWarning(String string) { + getBSkyBlock().logWarning(string); + } + + public void logError(String string) { + getBSkyBlock().logError(string); + } } diff --git a/src/main/java/us/tastybento/bskyblock/api/configuration/WorldSettings.java b/src/main/java/us/tastybento/bskyblock/api/configuration/WorldSettings.java index b2a3bf7fc..fa7c8142d 100644 --- a/src/main/java/us/tastybento/bskyblock/api/configuration/WorldSettings.java +++ b/src/main/java/us/tastybento/bskyblock/api/configuration/WorldSettings.java @@ -2,11 +2,14 @@ package us.tastybento.bskyblock.api.configuration; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.bukkit.GameMode; import org.bukkit.entity.EntityType; +import us.tastybento.bskyblock.api.addons.Addon; + /** * Contains world-specific settings. Only getters are required, but you may need setters for your own class. * @author tastybento @@ -156,30 +159,35 @@ public interface WorldSettings { * @return the onJoinResetMoney */ public boolean isOnJoinResetMoney(); - + /** * @return the onJoinResetInventory */ public boolean isOnJoinResetInventory(); - + /** * @return the onJoinResetEnderChest */ public boolean isOnJoinResetEnderChest(); - + /** * @return the onLeaveResetMoney */ public boolean isOnLeaveResetMoney(); - + /** * @return the onLeaveResetInventory */ public boolean isOnLeaveResetInventory(); - + /** * @return the onLeaveResetEnderChest */ public boolean isOnLeaveResetEnderChest(); + /** + * @return the Addon that registered this world + */ + public Optional getAddon(); + } diff --git a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminSchemCommand.java b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminSchemCommand.java index 9ab77ab03..b59a8bcc1 100644 --- a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminSchemCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminSchemCommand.java @@ -21,6 +21,7 @@ public class AdminSchemCommand extends CompositeCommand { super(parent, "schem"); } + @Override public void setup() { setPermission("admin.schem"); setParameters("commands.admin.schem.parameters"); @@ -29,13 +30,14 @@ public class AdminSchemCommand extends CompositeCommand { clipboards = new HashMap<>(); } + @Override @SuppressWarnings("deprecation") public boolean execute(User user, List args) { if (args.isEmpty()) { showHelp(this, user); return false; } - Clipboard cb = clipboards.getOrDefault(user.getUniqueId(), new Clipboard(getPlugin())); + Clipboard cb = clipboards.getOrDefault(user.getUniqueId(), new Clipboard(getPlugin(), getPlugin().getDataFolder())); if (args.get(0).equalsIgnoreCase("paste")) { if (cb.isFull()) { @@ -71,7 +73,7 @@ public class AdminSchemCommand extends CompositeCommand { if (b != null) { cb.setOrigin(b.getLocation()); user.getPlayer().sendBlockChange(b.getLocation(), Material.STAINED_GLASS,(byte)14); - Bukkit.getScheduler().runTaskLater(getPlugin(), + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> user.getPlayer().sendBlockChange(b.getLocation(), b.getType(), b.getData()), 20L); user.sendMessage("general.success"); diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java index 873583f97..5b8bf2bc4 100644 --- a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java +++ b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java @@ -10,18 +10,18 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; +import org.bukkit.Bukkit; import org.bukkit.DyeColor; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Nameable; import org.bukkit.World; import org.bukkit.block.Banner; import org.bukkit.block.Block; @@ -34,10 +34,14 @@ import org.bukkit.block.banner.PatternType; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Entity; +import org.bukkit.entity.AbstractHorse; +import org.bukkit.entity.Ageable; +import org.bukkit.entity.ChestedHorse; import org.bukkit.entity.EntityType; +import org.bukkit.entity.Horse; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import org.bukkit.entity.Tameable; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; @@ -55,6 +59,8 @@ import org.bukkit.util.Vector; import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.api.localization.TextVariables; import us.tastybento.bskyblock.api.user.User; +import us.tastybento.bskyblock.database.objects.Island; +import us.tastybento.bskyblock.util.Util; public class Clipboard { @@ -84,19 +90,17 @@ public class Clipboard { private BSkyBlock plugin; private boolean copied; - // Pasted items - private Map> signs = new HashMap<>(); - private File schemFolder; - public Clipboard(BSkyBlock plugin) { + public Clipboard(BSkyBlock plugin, File schemFolder) { super(); this.plugin = plugin; - schemFolder = new File(plugin.getDataFolder(), "schems"); if (!schemFolder.exists()) { schemFolder.mkdirs(); } + this.schemFolder = schemFolder; } + /** * @return the pos1 */ @@ -187,31 +191,64 @@ public class Clipboard { } /** - * Pastes the clipboard to location - * @param location - location to paste + * Pastes the clipboard to island location + * @param world - world in which to paste + * @param island - location to paste + * @param task - task to run after pasting */ - public void paste(Location location) { - signs.clear(); - blockConfig.getConfigurationSection(BLOCK).getKeys(false).forEach(b -> pasteBlock(location, blockConfig.getConfigurationSection(BLOCK + "." + b))); + public void paste(World world, Island island, Runnable task) { + blockConfig.getConfigurationSection(BLOCK).getKeys(false).forEach(b -> pasteBlock(world, island, island.getCenter(), blockConfig.getConfigurationSection(BLOCK + "." + b))); + if (task != null) { + Bukkit.getScheduler().runTaskLater(plugin, task, 2L); + } } - private void pasteBlock(Location location, ConfigurationSection config) { + /** + * Paste clipboard at this location + * @param location + */ + public void paste(Location location) { + blockConfig.getConfigurationSection(BLOCK).getKeys(false).forEach(b -> pasteBlock(location.getWorld(), null, location, blockConfig.getConfigurationSection(BLOCK + "." + b))); + + } + + private void writeSign(Island island, Block block, List lines) { + Sign sign = (Sign) block.getState(); + org.bukkit.material.Sign s = (org.bukkit.material.Sign) sign.getData(); + // Handle spawn sign + if (!lines.isEmpty() && lines.get(0).equalsIgnoreCase(TextVariables.SPAWN_HERE)) { + block.setType(Material.AIR); + // Orient to face same direction as sign + Location spawnPoint = new Location(block.getWorld(), block.getX() + 0.5D, block.getY(), + block.getZ() + 0.5D, Util.blockFaceToFloat(s.getFacing().getOppositeFace()), 30F); + island.setSpawnPoint(block.getWorld().getEnvironment(), spawnPoint); + return; + } + // Sub in player's name + for (int i = 0 ; i < lines.size(); i++) { + sign.setLine(i, lines.get(i).replace(TextVariables.NAME, plugin.getPlayers().getName(island.getOwner()))); + } + sign.update(); + } + + + private void pasteBlock(World world, Island island, Location location, ConfigurationSection config) { String[] pos = config.getName().split(","); int x = location.getBlockX() + Integer.valueOf(pos[0]); int y = location.getBlockY() + Integer.valueOf(pos[1]); int z = location.getBlockZ() + Integer.valueOf(pos[2]); // Default type is air Material material = Material.getMaterial(config.getString("type", "AIR")); - Block block = location.getWorld().getBlockAt(x, y, z); + Block block = world.getBlockAt(x, y, z); if (config.getBoolean(ATTACHED)) { - plugin.getServer().getScheduler().runTask(plugin, () -> setBlock(block, config, material)); + plugin.getServer().getScheduler().runTask(plugin, () -> setBlock(island, block, config, material)); } else { - setBlock(block, config, material); + setBlock(island, block, config, material); } } @SuppressWarnings("deprecation") - private void setBlock(Block block, ConfigurationSection config, Material material) { + private void setBlock(Island island, Block block, ConfigurationSection config, Material material) { // Block state if (config.getBoolean(ATTACHED) && material.toString().contains("TORCH")) { @@ -270,17 +307,12 @@ public class Clipboard { } // Block data + // Signs if (bs instanceof Sign) { - Sign sign = (Sign)bs; List lines = config.getStringList("lines"); - for (int i =0 ; i < lines.size(); i++) { - sign.setLine(i, lines.get(i)); - } - sign.update(); - // Log the sign - signs.put(block.getLocation(), lines); - + writeSign(island, block, lines); } + // Banners if (bs instanceof Banner) { Banner banner = (Banner)bs; DyeColor baseColor = DyeColor.valueOf(config.getString("baseColor", "RED")); @@ -296,6 +328,7 @@ public class Clipboard { } bs.update(true, false); } + // Mob spawners if (bs instanceof CreatureSpawner) { CreatureSpawner spawner = ((CreatureSpawner) bs); spawner.setSpawnedType(EntityType.valueOf(config.getString("spawnedType", "PIG"))); @@ -308,7 +341,7 @@ public class Clipboard { spawner.setSpawnRange(config.getInt("spawnRange", 4)); bs.update(true, false); } - + // Chests, in general if (bs instanceof InventoryHolder) { bs.update(true, false); Inventory ih = ((InventoryHolder)bs).getInventory(); @@ -318,18 +351,50 @@ public class Clipboard { // Entities if (config.isConfigurationSection("entity")) { - ConfigurationSection e = config.getConfigurationSection("entity"); - e.getKeys(false).forEach(k -> { + ConfigurationSection en = config.getConfigurationSection("entity"); + en.getKeys(false).forEach(k -> { + ConfigurationSection ent = en.getConfigurationSection(k); Location center = block.getLocation().add(new Vector(0.5, 0.0, 0.5)); - LivingEntity ent = (LivingEntity)block.getWorld().spawnEntity(center, EntityType.valueOf(e.getString(k + ".type", "PIG"))); - ent.setCustomName(e.getString(k + ".name")); + LivingEntity e = (LivingEntity)block.getWorld().spawnEntity(center, EntityType.valueOf(ent.getString("type", "PIG"))); + if (e instanceof Nameable) { + e.setCustomName(ent.getString("name")); + } + if (e instanceof Colorable) { + if (ent.contains("color")) { + ((Colorable) e).setColor(DyeColor.valueOf(ent.getString("color"))); + } + } + if (e instanceof Tameable) { + ((Tameable)e).setTamed(ent.getBoolean("tamed")); + } + if (e instanceof ChestedHorse) { + ((ChestedHorse)e).setCarryingChest(ent.getBoolean("chest")); + } + if (e instanceof Ageable) { + if (ent.getBoolean("adult")) { + ((Ageable)e).setAdult(); + } else { + ((Ageable)e).setBaby(); + } + } + if (e instanceof AbstractHorse) { + AbstractHorse horse = (AbstractHorse)e; + horse.setDomestication(ent.getInt("domestication")); + ConfigurationSection inv = ent.getConfigurationSection("inventory"); + inv.getKeys(false).forEach(i -> horse.getInventory().setItem(Integer.valueOf(i), (ItemStack)inv.get(i))); + } + + if (e instanceof AbstractHorse) { + Horse horse = (Horse)e; + horse.setStyle(Horse.Style.valueOf(ent.getString("style", "NONE"))); + } }); } } @SuppressWarnings("deprecation") - private boolean copyBlock(Block block, Location copyOrigin, boolean copyAir, Collection entities) { + private boolean copyBlock(Block block, Location copyOrigin, boolean copyAir, Collection entities) { if (!copyAir && block.getType().equals(Material.AIR) && entities.isEmpty()) { return false; } @@ -343,9 +408,40 @@ public class Clipboard { ConfigurationSection s = blockConfig.createSection(BLOCK + "." + pos); // Set entities - for (Entity e: entities) { - s.set("entity." + e.getUniqueId() + ".type", e.getType().name()); - s.set("entity." + e.getUniqueId() + ".name", e.getCustomName()); + for (LivingEntity e: entities) { + ConfigurationSection en = s.createSection("entity." + e.getUniqueId()); + en.set("type", e.getType().name()); + if (e instanceof Nameable) { + en.set("name", e.getCustomName()); + } + if (e instanceof Colorable) { + Colorable c = (Colorable)e; + en.set("color", c.getColor().name()); + } + if (e instanceof Tameable && ((Tameable)e).isTamed()) { + en.set("tamed", true); + } + if (e instanceof ChestedHorse && ((ChestedHorse)e).isCarryingChest()) { + en.set("chest", true); + } + if (e instanceof Ageable) { + en.set("adult", ((Ageable)e).isAdult()); + } + if (e instanceof AbstractHorse) { + AbstractHorse horse = (AbstractHorse)e; + en.set("domestication", horse.getDomestication()); + for (int index = 0; index < horse.getInventory().getSize(); index++) { + ItemStack i = horse.getInventory().getItem(index); + if (i != null) { + en.set("inventory." + index, i); + } + } + } + + if (e instanceof Horse) { + Horse horse = (Horse)e; + en.set("style", horse.getStyle().name()); + } } // Return if this is just air block @@ -438,13 +534,6 @@ public class Clipboard { return blockConfig; } - /** - * @return the signs - */ - public Map> getSigns() { - plugin.log("DEBUG: signs " + signs.size()); - return signs; - } private void unzip(final String zipFilePath) throws IOException { Path path = Paths.get(zipFilePath); if (!(path.toFile().exists())) { @@ -574,4 +663,6 @@ public class Clipboard { user.sendMessage("general.success"); return true; } + + } diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java b/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java index b158f26e4..42647ea12 100644 --- a/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java +++ b/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java @@ -1,26 +1,11 @@ package us.tastybento.bskyblock.island.builders; -import java.io.File; -import java.io.IOException; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.World; import org.bukkit.World.Environment; -import org.bukkit.block.Sign; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.entity.Player; import us.tastybento.bskyblock.BSkyBlock; -import us.tastybento.bskyblock.api.localization.TextVariables; import us.tastybento.bskyblock.database.objects.Island; -import us.tastybento.bskyblock.util.Util; /** * Generates islands @@ -33,68 +18,13 @@ public class IslandBuilder { private Island island; private World world; private Environment type = Environment.NORMAL; - private UUID playerUUID; - private String playerName; private BSkyBlock plugin; - private Map islandSchems = new EnumMap<>(Environment.class); - private Location spawnPoint; private Runnable task; - //TODO support companions? - public IslandBuilder(BSkyBlock plugin, Island island) { this.plugin = plugin; this.island = island; world = island.getWorld(); - loadIslands(); - } - - private void loadIslands() { - File schems = new File(plugin.getDataFolder(), "schems"); - if (!schems.exists()) { - if (!schems.mkdirs()) { - plugin.logError("Could not make schems folder!"); - } else { - copySchems(schems); - } - } - - try { - Clipboard cb = new Clipboard(plugin); - cb.load("island"); - islandSchems.put(Environment.NORMAL, cb); - } catch (IOException | InvalidConfigurationException e) { - plugin.logError("Could not load default island"); - } - if (plugin.getSettings().isNetherGenerate() && plugin.getSettings().isNetherIslands()) { - try { - Clipboard cbn = new Clipboard(plugin); - cbn.load("nether-island"); - islandSchems.put(Environment.NETHER, cbn); - } catch (IOException | InvalidConfigurationException e) { - plugin.logError("Could not load default nether island"); - } - } - if (plugin.getSettings().isEndGenerate() && plugin.getSettings().isEndIslands()) { - try { - Clipboard cbe = new Clipboard(plugin); - cbe.load("end-island"); - islandSchems.put(Environment.THE_END, cbe); - } catch (IOException | InvalidConfigurationException e) { - plugin.logError("Could not load default end island"); - } - } - plugin.log("Loaded " + islandSchems.size() + " islands"); - } - - /** - * Copies schems from the jar file - * @param schems2 - file containing schem - */ - private void copySchems(File schems2) { - plugin.saveResource("schems/island.schem", false); - plugin.saveResource("schems/nether-island.schem", false); - plugin.saveResource("schems/end-island.schem", false); } /** @@ -105,15 +35,6 @@ public class IslandBuilder { return this; } - /** - * @param player - the player the player to set - */ - public IslandBuilder setPlayer(Player player) { - playerUUID = player.getUniqueId(); - playerName = player.getName(); - return this; - } - /** * The task to run when the island is built * @param task @@ -126,7 +47,6 @@ public class IslandBuilder { public void build() { plugin.log("Pasting island to " + type); - Location loc = island.getCenter(); // Switch on island type switch (type) { case NETHER: @@ -134,54 +54,19 @@ public class IslandBuilder { if (world == null) { return; } - loc = island.getCenter().toVector().toLocation(world); break; case THE_END: world = Bukkit.getWorld(island.getWorld().getName() + "_the_end"); if (world == null) { return; } - loc = island.getCenter().toVector().toLocation(world); break; default: break; } - islandSchems.get(type).paste(loc); - // Do other stuff - // Handle signs - signs are attachable, so they are not there until 1 tick after pasting - if (playerUUID != null) { - Bukkit.getScheduler().runTaskLater(plugin, () -> islandSchems.get(type).getSigns().forEach(this::writeSign), 2L); - } - if (task != null) { - Bukkit.getScheduler().runTaskLater(plugin, task, 3L); - } + plugin.getSchemsManager().paste(world, island, task); } - private void writeSign(Location loc, List lines) { - Sign sign = (Sign) loc.getBlock().getState(); - org.bukkit.material.Sign s = (org.bukkit.material.Sign) sign.getData(); - lines.forEach(plugin::log); - // Handle spawn sign - if (!lines.isEmpty() && lines.get(0).equalsIgnoreCase(TextVariables.SPAWN_HERE)) { - loc.getBlock().setType(Material.AIR); - // Orient to face same direction as sign - spawnPoint = new Location(loc.getWorld(), loc.getBlockX() + 0.5D, loc.getBlockY(), - loc.getBlockZ() + 0.5D, Util.blockFaceToFloat(s.getFacing().getOppositeFace()), 30F); - return; - } - // Sub in player's name - for (int i = 0 ; i < lines.size(); i++) { - sign.setLine(i, lines.get(i).replace(TextVariables.NAME, playerName)); - } - sign.update(); - } - - /** - * @return the spawnPoint - */ - public Optional getSpawnPoint() { - return Optional.ofNullable(spawnPoint); - } } diff --git a/src/main/java/us/tastybento/bskyblock/managers/IslandWorldManager.java b/src/main/java/us/tastybento/bskyblock/managers/IslandWorldManager.java index 04a73ecbf..938c1a82d 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/IslandWorldManager.java +++ b/src/main/java/us/tastybento/bskyblock/managers/IslandWorldManager.java @@ -1,8 +1,10 @@ package us.tastybento.bskyblock.managers; +import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -16,6 +18,7 @@ import org.bukkit.WorldType; import org.bukkit.entity.EntityType; import us.tastybento.bskyblock.BSkyBlock; +import us.tastybento.bskyblock.api.addons.Addon; import us.tastybento.bskyblock.api.configuration.WorldSettings; import us.tastybento.bskyblock.api.flags.Flag; import us.tastybento.bskyblock.api.user.User; @@ -495,42 +498,42 @@ public class IslandWorldManager { public Set getRemoveMobsWhitelist(World world) { return worldSettings.get(Util.getWorld(world)).getRemoveMobsWhitelist(); } - + /** * @return the onJoinResetMoney */ public boolean isOnJoinResetMoney(World world) { return worldSettings.get(Util.getWorld(world)).isOnJoinResetMoney(); } - + /** * @return the onJoinResetInventory */ public boolean isOnJoinResetInventory(World world) { return worldSettings.get(Util.getWorld(world)).isOnJoinResetInventory(); } - + /** * @return the onJoinResetEnderChest */ public boolean isOnJoinResetEnderChest(World world) { return worldSettings.get(Util.getWorld(world)).isOnJoinResetEnderChest(); } - + /** * @return the onLeaveResetMoney */ public boolean isOnLeaveResetMoney(World world) { return worldSettings.get(Util.getWorld(world)).isOnLeaveResetMoney(); } - + /** * @return the onLeaveResetInventory */ public boolean isOnLeaveResetInventory(World world) { return worldSettings.get(Util.getWorld(world)).isOnLeaveResetInventory(); } - + /** * @return the onLeaveResetEnderChest */ @@ -538,4 +541,21 @@ public class IslandWorldManager { return worldSettings.get(Util.getWorld(world)).isOnLeaveResetEnderChest(); } + /** + * The data folder for the addon that registered this world, or the plugin's data folder if none found + * @return + */ + public File getDataFolder(World world) { + return worldSettings.get(Util.getWorld(world)).getAddon().map(Addon::getDataFolder).orElse(plugin.getDataFolder()); + } + + /** + * Get the addon associated with this world set + * @param world - world + * @return Addon, or empty + */ + public Optional getAddon(World world) { + return worldSettings.get(Util.getWorld(world)).getAddon(); + } + } diff --git a/src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java b/src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java new file mode 100644 index 000000000..a5d7259da --- /dev/null +++ b/src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java @@ -0,0 +1,105 @@ +package us.tastybento.bskyblock.managers; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import org.bukkit.World; +import org.bukkit.configuration.InvalidConfigurationException; + +import us.tastybento.bskyblock.BSkyBlock; +import us.tastybento.bskyblock.api.addons.Addon; +import us.tastybento.bskyblock.database.objects.Island; +import us.tastybento.bskyblock.island.builders.Clipboard; + +public class SchemsManager { + + private BSkyBlock plugin; + private Map islandSchems; + + /** + * @param plugin + */ + public SchemsManager(BSkyBlock plugin) { + this.plugin = plugin; + islandSchems = new HashMap<>(); + } + + private void copySchems(File schems, World world, String name) { + if (!schems.exists()) { + if (!schems.mkdirs()) { + plugin.logError("Could not make schems folder!"); + } else { + Optional addon = plugin.getIWM().getAddon(world); + addon.ifPresent(a -> a.saveResource("schems/" + name, false)); + if (!addon.isPresent()) { + plugin.saveResource("schems/" + name, false); + } + } + } + + } + + public Clipboard get(World world) { + return islandSchems.get(world); + } + + /** + * Load schems for world. Will try and load nether and end schems too if settings are set. + * @param world - world + */ + public void loadIslands(World world) { + if (plugin.getSchemsManager().loadSchem(world, "island")) { + plugin.log("Loaded island for " + plugin.getIWM().getFriendlyName(world)); + } else { + plugin.logError("Could not load island for " + plugin.getIWM().getFriendlyName(world)); + } + if (plugin.getIWM().isNetherGenerate(world) && plugin.getIWM().isNetherIslands(world)) { + + if (plugin.getSchemsManager().loadSchem(plugin.getIWM().getNetherWorld(world), "nether-island")) { + plugin.log("Loaded nether island for " + plugin.getIWM().getFriendlyName(world)); + } else { + plugin.logError("Could not load nether island for " + plugin.getIWM().getFriendlyName(world)); + } + } + if (plugin.getIWM().isEndGenerate(world) && plugin.getIWM().isEndIslands(world)) { + if (plugin.getSchemsManager().loadSchem(plugin.getIWM().getEndWorld(world), "end-island")) { + plugin.log("Loaded end island for " + plugin.getIWM().getFriendlyName(world)); + } else { + plugin.logError("Could not load end island for " + plugin.getIWM().getFriendlyName(world)); + } + } + + + } + + private boolean loadSchem(World world, String name) { + File schems = new File(plugin.getIWM().getDataFolder(world), "schems"); + copySchems(schems, world, name); + try { + Clipboard cb = new Clipboard(plugin, schems); + cb.load(name); + islandSchems.put(world, cb); + } catch (IOException | InvalidConfigurationException e) { + plugin.logError("Could not load " + name + " schem"); + e.printStackTrace(); + return false; + } + return true; + } + + /** + * Paste the schem for world to the island center location and run task afterwards + * @param world - world to paste to + * @param island - the island who owns this schem + * @param task - task to run after pasting is completed + */ + public void paste(World world, Island island, Runnable task) { + if (islandSchems.containsKey(world)) { + islandSchems.get(world).paste(world, island, task); + } + } + +} diff --git a/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java b/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java index ec13941b0..12f738cc7 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java +++ b/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java @@ -122,42 +122,24 @@ public class NewIsland { return; } // Create island - IslandBuilder ib = new IslandBuilder(plugin, island) - .setPlayer(user.getPlayer()) - .setType(Environment.NORMAL); - ib.run(() -> { + new IslandBuilder(plugin, island).setType(Environment.NORMAL).run(() -> { // Set initial spawn point if one exists - ib.getSpawnPoint().ifPresent(l -> { - plugin.getPlayers().setHomeLocation(user, l, 1); - island.setSpawnPoint(Environment.NORMAL, l); - }); + if (island.getSpawnPoint(Environment.NORMAL) != null) { + plugin.log("DEBUG: spawn point = " + island.getSpawnPoint(Environment.NORMAL)); + plugin.getPlayers().setHomeLocation(user, island.getSpawnPoint(Environment.NORMAL), 1); + } // Teleport player after this island is built plugin.getIslands().homeTeleport(world, user.getPlayer(), true); - }); - // Build it - ib.build(); + }).build(); // Make nether island if (plugin.getSettings().isNetherGenerate() && plugin.getSettings().isNetherIslands() && plugin.getIWM().getNetherWorld() != null) { - IslandBuilder ib_nether = new IslandBuilder(plugin, island) - .setPlayer(user.getPlayer()) - .setType(Environment.NETHER); - ib_nether.run(() -> ib_nether.getSpawnPoint().ifPresent(l -> island.setSpawnPoint(Environment.NETHER, l))); - // Build it - ib_nether.build(); + new IslandBuilder(plugin, island).setType(Environment.NETHER).build(); } // Make end island if (plugin.getSettings().isEndGenerate() && plugin.getSettings().isEndIslands() && plugin.getIWM().getEndWorld() != null) { - IslandBuilder ib_end = new IslandBuilder(plugin, island) - .setPlayer(user.getPlayer()) - .setType(Environment.THE_END); - ib_end.run(() -> { - // Set initial spawn point if one exists - ib_end.getSpawnPoint().ifPresent(l -> island.setSpawnPoint(Environment.NETHER, l)); - }); - // Build it - ib_end.build(); + new IslandBuilder(plugin, island).setType(Environment.THE_END).build(); } // Fire exit event From 35247965faa29bc99429f0d3000e048f1317c966 Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 2 Jul 2018 20:35:21 -0700 Subject: [PATCH 07/14] WIP - still need to fix bedrock saving in schem --- .../bskyblock/island/builders/Clipboard.java | 24 ++++++- .../island/builders/IslandBuilder.java | 72 ------------------- .../bskyblock/managers/SchemsManager.java | 31 +++++--- .../bskyblock/managers/island/NewIsland.java | 10 ++- 4 files changed, 46 insertions(+), 91 deletions(-) delete mode 100644 src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java index 5b8bf2bc4..7c9936188 100644 --- a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java +++ b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java @@ -179,6 +179,10 @@ public class Clipboard { maxZ = Math.max(maxZ, z); count ++; } + if (block.getType().equals(Material.BEDROCK)) { + plugin.log("DEBUG: setting bedrock to " + x + "," + y + "," + z); + blockConfig.set("bedrock", x + "," + y + "," + z); + } } } } @@ -197,7 +201,17 @@ public class Clipboard { * @param task - task to run after pasting */ public void paste(World world, Island island, Runnable task) { - blockConfig.getConfigurationSection(BLOCK).getKeys(false).forEach(b -> pasteBlock(world, island, island.getCenter(), blockConfig.getConfigurationSection(BLOCK + "." + b))); + // Offset due to bedrock + Vector off = new Vector(0,0,0); + if (blockConfig.contains("bedrock")) { + String[] offset = blockConfig.getString("bedrock").split(","); + off = new Vector(Integer.valueOf(offset[0]), Integer.valueOf(offset[1]), Integer.valueOf(offset[2])); + } + // Calculate location for pasting + Location loc = island.getCenter().toVector().subtract(off).toLocation(world); + // Paste + blockConfig.getConfigurationSection(BLOCK).getKeys(false).forEach(b -> pasteBlock(world, island, loc, blockConfig.getConfigurationSection(BLOCK + "." + b))); + // Run follow on task if it exists if (task != null) { Bukkit.getScheduler().runTaskLater(plugin, task, 2L); } @@ -226,7 +240,13 @@ public class Clipboard { } // Sub in player's name for (int i = 0 ; i < lines.size(); i++) { - sign.setLine(i, lines.get(i).replace(TextVariables.NAME, plugin.getPlayers().getName(island.getOwner()))); + sign.setLine(i, lines + .get(i) + .replace(TextVariables.NAME, + plugin + .getPlayers() + .getName(island + .getOwner()))); } sign.update(); } diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java b/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java deleted file mode 100644 index 42647ea12..000000000 --- a/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java +++ /dev/null @@ -1,72 +0,0 @@ -package us.tastybento.bskyblock.island.builders; - -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.World.Environment; - -import us.tastybento.bskyblock.BSkyBlock; -import us.tastybento.bskyblock.database.objects.Island; - -/** - * Generates islands - * - * @author tastybento - * @since 1.0 - */ -public class IslandBuilder { - - private Island island; - private World world; - private Environment type = Environment.NORMAL; - private BSkyBlock plugin; - private Runnable task; - - public IslandBuilder(BSkyBlock plugin, Island island) { - this.plugin = plugin; - this.island = island; - world = island.getWorld(); - } - - /** - * @param type the type to set - */ - public IslandBuilder setType(Environment type) { - this.type = type; - return this; - } - - /** - * The task to run when the island is built - * @param task - * @return IslandBuilder - */ - public IslandBuilder run(Runnable task) { - this.task = task; - return this; - } - - public void build() { - plugin.log("Pasting island to " + type); - // Switch on island type - switch (type) { - case NETHER: - world = Bukkit.getWorld(island.getWorld().getName() + "_nether"); - if (world == null) { - return; - } - break; - case THE_END: - world = Bukkit.getWorld(island.getWorld().getName() + "_the_end"); - if (world == null) { - return; - } - break; - default: - break; - } - plugin.getSchemsManager().paste(world, island, task); - } - -} - - diff --git a/src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java b/src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java index a5d7259da..f04a89036 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java +++ b/src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java @@ -28,18 +28,17 @@ public class SchemsManager { } private void copySchems(File schems, World world, String name) { - if (!schems.exists()) { - if (!schems.mkdirs()) { - plugin.logError("Could not make schems folder!"); - } else { - Optional addon = plugin.getIWM().getAddon(world); - addon.ifPresent(a -> a.saveResource("schems/" + name, false)); - if (!addon.isPresent()) { - plugin.saveResource("schems/" + name, false); - } - } - } + if (!schems.exists() && !schems.mkdirs()) { + plugin.logError("Could not make schems folder!"); + return; + } + Optional addon = plugin.getIWM().getAddon(world); + if (addon.isPresent()) { + addon.get().saveResource("schems/" + name + ".schem", false); + } else { + plugin.saveResource("schems/" + name + ".schem", false); + } } public Clipboard get(World world) { @@ -102,4 +101,14 @@ public class SchemsManager { } } + /** + * Paste the schem to world for island + * @param world + * @param island + */ + public void paste(World world, Island island) { + paste(world, island, null); + + } + } diff --git a/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java b/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java index 12f738cc7..8a396f177 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java +++ b/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java @@ -12,7 +12,6 @@ import us.tastybento.bskyblock.api.events.island.IslandEvent; import us.tastybento.bskyblock.api.events.island.IslandEvent.Reason; import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.database.objects.Island; -import us.tastybento.bskyblock.island.builders.IslandBuilder; /** * Create and paste a new island @@ -122,24 +121,23 @@ public class NewIsland { return; } // Create island - new IslandBuilder(plugin, island).setType(Environment.NORMAL).run(() -> { + plugin.getSchemsManager().paste(world, island, () -> { // Set initial spawn point if one exists if (island.getSpawnPoint(Environment.NORMAL) != null) { - plugin.log("DEBUG: spawn point = " + island.getSpawnPoint(Environment.NORMAL)); plugin.getPlayers().setHomeLocation(user, island.getSpawnPoint(Environment.NORMAL), 1); } // Teleport player after this island is built plugin.getIslands().homeTeleport(world, user.getPlayer(), true); - }).build(); + }); // Make nether island if (plugin.getSettings().isNetherGenerate() && plugin.getSettings().isNetherIslands() && plugin.getIWM().getNetherWorld() != null) { - new IslandBuilder(plugin, island).setType(Environment.NETHER).build(); + plugin.getSchemsManager().paste(plugin.getIWM().getNetherWorld(world), island); } // Make end island if (plugin.getSettings().isEndGenerate() && plugin.getSettings().isEndIslands() && plugin.getIWM().getEndWorld() != null) { - new IslandBuilder(plugin, island).setType(Environment.THE_END).build(); + plugin.getSchemsManager().paste(plugin.getIWM().getEndWorld(world), island); } // Fire exit event From 693625ab9ad3ddb7a1bb798a2ed5175abdd6688f Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 2 Jul 2018 22:01:37 -0700 Subject: [PATCH 08/14] Added placement based on bedrock. --- .../bskyblock/island/builders/Clipboard.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java index 7c9936188..99a09d220 100644 --- a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java +++ b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java @@ -179,10 +179,6 @@ public class Clipboard { maxZ = Math.max(maxZ, z); count ++; } - if (block.getType().equals(Material.BEDROCK)) { - plugin.log("DEBUG: setting bedrock to " + x + "," + y + "," + z); - blockConfig.set("bedrock", x + "," + y + "," + z); - } } } } @@ -230,7 +226,7 @@ public class Clipboard { Sign sign = (Sign) block.getState(); org.bukkit.material.Sign s = (org.bukkit.material.Sign) sign.getData(); // Handle spawn sign - if (!lines.isEmpty() && lines.get(0).equalsIgnoreCase(TextVariables.SPAWN_HERE)) { + if (island != null && !lines.isEmpty() && lines.get(0).equalsIgnoreCase(TextVariables.SPAWN_HERE)) { block.setType(Material.AIR); // Orient to face same direction as sign Location spawnPoint = new Location(block.getWorld(), block.getX() + 0.5D, block.getY(), @@ -238,15 +234,13 @@ public class Clipboard { island.setSpawnPoint(block.getWorld().getEnvironment(), spawnPoint); return; } + String name = TextVariables.NAME; + if (island != null) { + name = plugin.getPlayers().getName(island.getOwner()); + } // Sub in player's name for (int i = 0 ; i < lines.size(); i++) { - sign.setLine(i, lines - .get(i) - .replace(TextVariables.NAME, - plugin - .getPlayers() - .getName(island - .getOwner()))); + sign.setLine(i, lines.get(i).replace(TextVariables.NAME, name)); } sign.update(); } @@ -474,6 +468,9 @@ public class Clipboard { if (block.getData() != 0) { s.set("data", block.getData()); } + if (block.getType().equals(Material.BEDROCK)) { + blockConfig.set("bedrock", x + "," + y + "," + z); + } // Block state BlockState bs = block.getState(); From 0cb21d84683a14aca1d4dfd5eef8c922d34c055f Mon Sep 17 00:00:00 2001 From: Florian CUNY Date: Tue, 3 Jul 2018 11:19:48 +0200 Subject: [PATCH 09/14] Fixed NPE when the ItemParser returns null when the locale banner is an invalid String or does not exist --- .../tastybento/bskyblock/panels/LanguagePanel.java | 14 ++++++++++++-- .../us/tastybento/bskyblock/util/ItemParser.java | 4 ++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/us/tastybento/bskyblock/panels/LanguagePanel.java b/src/main/java/us/tastybento/bskyblock/panels/LanguagePanel.java index 1cc2a9c0e..e725fa695 100644 --- a/src/main/java/us/tastybento/bskyblock/panels/LanguagePanel.java +++ b/src/main/java/us/tastybento/bskyblock/panels/LanguagePanel.java @@ -2,6 +2,8 @@ package us.tastybento.bskyblock.panels; import java.util.Locale; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.api.panels.builders.PanelBuilder; import us.tastybento.bskyblock.api.panels.builders.PanelItemBuilder; @@ -23,8 +25,16 @@ public class LanguagePanel { .name(user.getTranslation("language.panel-title")); for (Locale locale : BSkyBlock.getInstance().getLocalesManager().getAvailableLocales(true)) { - PanelItemBuilder localeIcon = new PanelItemBuilder().icon(BSkyBlock.getInstance().getLocalesManager().getLanguages().get(locale).getBanner()) - .name(fancyLocaleDisplayName(user, locale)) + PanelItemBuilder localeIcon = new PanelItemBuilder(); + + ItemStack localeBanner = BSkyBlock.getInstance().getLocalesManager().getLanguages().get(locale).getBanner(); + if (localeBanner != null) { + localeIcon.icon(localeBanner); + } else { + localeIcon.icon(new ItemStack(Material.BANNER, 1)); // Set to a blank banner. + } + + localeIcon.name(fancyLocaleDisplayName(user, locale)) .clickHandler((panel, u, click, slot) -> { BSkyBlock.getInstance().getPlayers().setLocale(u.getUniqueId(), locale.toLanguageTag()); u.sendMessage("language.edited", "[lang]", fancyLocaleDisplayName(u, locale)); diff --git a/src/main/java/us/tastybento/bskyblock/util/ItemParser.java b/src/main/java/us/tastybento/bskyblock/util/ItemParser.java index 0d823927f..42a4653e0 100644 --- a/src/main/java/us/tastybento/bskyblock/util/ItemParser.java +++ b/src/main/java/us/tastybento/bskyblock/util/ItemParser.java @@ -147,10 +147,10 @@ public class ItemParser { return result; } else { - return new ItemStack(Material.BANNER, 1); // Return a blank banner + return null; } } catch (Exception e) { - return new ItemStack(Material.BANNER, 1); // Return a blank banner + return null; } } } From 9f3e4e22dc389b629492399cf7c3d33e74b82f9b Mon Sep 17 00:00:00 2001 From: Florian CUNY Date: Tue, 3 Jul 2018 11:20:52 +0200 Subject: [PATCH 10/14] Tells how much time it took to fully load BSkyBlock --- src/main/java/us/tastybento/bskyblock/BSkyBlock.java | 6 ++++-- .../us/tastybento/bskyblock/managers/SchemsManager.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/us/tastybento/bskyblock/BSkyBlock.java b/src/main/java/us/tastybento/bskyblock/BSkyBlock.java index e9d4616ed..a78a7ff60 100755 --- a/src/main/java/us/tastybento/bskyblock/BSkyBlock.java +++ b/src/main/java/us/tastybento/bskyblock/BSkyBlock.java @@ -63,6 +63,9 @@ public class BSkyBlock extends JavaPlugin { @Override public void onEnable(){ + // Store the current millis time so we can tell how many ms it took for BSB to fully load. + final long startMillis = System.currentTimeMillis(); + // Save the default config from config.yml saveDefaultConfig(); setInstance(this); @@ -116,7 +119,6 @@ public class BSkyBlock extends JavaPlugin { // Enable addons addonsManager.enableAddons(); - getServer().getScheduler().runTask(instance, () -> { // Load Flags flagsManager = new FlagsManager(instance); @@ -128,7 +130,6 @@ public class BSkyBlock extends JavaPlugin { islandsManager.load(); // Save islands & players data asynchronously every X minutes - instance.getServer().getScheduler().runTaskTimer(instance, () -> { playersManager.save(true); islandsManager.save(true); @@ -136,6 +137,7 @@ public class BSkyBlock extends JavaPlugin { instance.log("#############################################"); instance.log(instance.getDescription().getFullName() + " has been fully enabled."); + instance.log("It took: " + (System.currentTimeMillis() - startMillis + "ms")); instance.log("Thanks for using our plugin !"); instance.log("- Tastybento and Poslovitch, 2017-2018"); instance.log("#############################################"); diff --git a/src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java b/src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java index f04a89036..feb32bf92 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java +++ b/src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java @@ -31,8 +31,8 @@ public class SchemsManager { if (!schems.exists() && !schems.mkdirs()) { plugin.logError("Could not make schems folder!"); return; - } + Optional addon = plugin.getIWM().getAddon(world); if (addon.isPresent()) { addon.get().saveResource("schems/" + name + ".schem", false); From 4245ebaa3392375b326148eddc616078c48a4315 Mon Sep 17 00:00:00 2001 From: tastybento Date: Tue, 3 Jul 2018 09:41:09 -0700 Subject: [PATCH 11/14] Fix banner parsing issue --- src/main/java/us/tastybento/bskyblock/util/ItemParser.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/us/tastybento/bskyblock/util/ItemParser.java b/src/main/java/us/tastybento/bskyblock/util/ItemParser.java index 42a4653e0..443715eff 100644 --- a/src/main/java/us/tastybento/bskyblock/util/ItemParser.java +++ b/src/main/java/us/tastybento/bskyblock/util/ItemParser.java @@ -132,11 +132,11 @@ public class ItemParser { if (part.length == 2) { return new ItemStack(Material.BANNER, Integer.parseInt(part[1])); } - if (part.length > 3) { + if (part.length >= 3) { int reqAmount = Integer.parseInt(part[1]); @SuppressWarnings("deprecation") - ItemStack result = new ItemStack(Material.BANNER, reqAmount, (short) DyeColor.valueOf(part[2]).getDyeData()); + ItemStack result = new ItemStack(Material.BANNER, reqAmount, DyeColor.valueOf(part[2]).getDyeData()); BannerMeta meta = (BannerMeta) result.getItemMeta(); for (int i = 3; i < part.length; i += 2) { From 284839c6a4b63673efd789dccaa506b751629696 Mon Sep 17 00:00:00 2001 From: tastybento Date: Tue, 3 Jul 2018 09:51:21 -0700 Subject: [PATCH 12/14] Added 2 more tests to banner parsing --- .../bskyblock/util/ItemParserTest.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/test/java/us/tastybento/bskyblock/util/ItemParserTest.java b/src/test/java/us/tastybento/bskyblock/util/ItemParserTest.java index 4de239cdb..22d4de255 100644 --- a/src/test/java/us/tastybento/bskyblock/util/ItemParserTest.java +++ b/src/test/java/us/tastybento/bskyblock/util/ItemParserTest.java @@ -9,6 +9,7 @@ import java.util.Arrays; import java.util.List; import org.bukkit.Bukkit; +import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemFactory; @@ -16,6 +17,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.BannerMeta; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.inventory.meta.SpawnEggMeta; +import org.bukkit.material.MaterialData; import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionType; import org.junit.Before; @@ -183,7 +185,7 @@ public class ItemParserTest { assertEquals(3, result.getAmount()); } } - } + } } } @@ -193,22 +195,24 @@ public class ItemParserTest { assertEquals(Material.TIPPED_ARROW, result.getType()); } - + @Test public void testParseBannerSimple() { ItemStack result = ItemParser.parse("BANNER:2"); assertEquals(Material.BANNER, result.getType()); assertEquals(2, result.getAmount()); } - + + @SuppressWarnings("deprecation") @Test public void testParseBannerThreeArgs() { // Germany ItemStack result = ItemParser.parse("BANNER:1:RED"); assertEquals(Material.BANNER, result.getType()); assertEquals(1, result.getAmount()); + assertEquals(new MaterialData(Material.BANNER, DyeColor.RED.getDyeData()), result.getData()); } - + @Test public void testParseBanner() { // Germany - two patterns @@ -216,6 +220,14 @@ public class ItemParserTest { Mockito.verify(bannerMeta, Mockito.times(2)).addPattern(Mockito.any()); } + @Test + public void testParseBannerTooManyColons() { + ItemStack result = ItemParser.parse("BANNER:1::::::::::::::"); + Mockito.verify(bannerMeta, Mockito.never()).addPattern(Mockito.any()); + assertEquals(Material.BANNER, result.getType()); + assertEquals(1, result.getAmount()); + } + @Test public void testParseTwoItem() { ItemStack result = ItemParser.parse("STONE:5"); From 265f05529b48e393a24f5921ed510406e26c55fc Mon Sep 17 00:00:00 2001 From: tastybento Date: Tue, 3 Jul 2018 11:05:14 -0700 Subject: [PATCH 13/14] Schems save in the respective addon data folders --- locales/en-US.yml | 3 ++- .../commands/admin/AdminSchemCommand.java | 16 ++++++++++++++-- .../bskyblock/island/builders/Clipboard.java | 6 +++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/locales/en-US.yml b/locales/en-US.yml index b39d19772..e699f66e8 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -127,9 +127,10 @@ commands: parameters: "" description: "manipulate schems" copy-first: "&cCopy a schem first!" + file-exists: "&cFile already exists, overwrite?" no-such-file: "&cNo such file!" could-not-load: "&cCould not load that file!" - could-not-save: "&Hmm, something went wrong saving that file: [message]" + could-not-save: "&cHmm, something went wrong saving that file: [message]" set-pos1: "&aPosition 1 set at [vector]" set-pos2: "&aPosition 2 set at [vector]" set-different-pos: "&cSet a different location - this pos is already set!" diff --git a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminSchemCommand.java b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminSchemCommand.java index b59a8bcc1..365712336 100644 --- a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminSchemCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminSchemCommand.java @@ -1,5 +1,6 @@ package us.tastybento.bskyblock.commands.admin; +import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,7 +38,10 @@ public class AdminSchemCommand extends CompositeCommand { showHelp(this, user); return false; } - Clipboard cb = clipboards.getOrDefault(user.getUniqueId(), new Clipboard(getPlugin(), getPlugin().getDataFolder())); + File schemFolder = new File(getIWM().getDataFolder(getWorld()), "schems"); + getPlugin().log("DEBUG: schemFolder = " + schemFolder.getAbsolutePath()); + getPlugin().log(getIWM().getAddon(getWorld()).map(a -> "Addon = " + a.toString() + " data folder = " + a.getDataFolder().getAbsolutePath()).orElse("Not addon")); + Clipboard cb = clipboards.getOrDefault(user.getUniqueId(), new Clipboard(getPlugin(), schemFolder)); if (args.get(0).equalsIgnoreCase("paste")) { if (cb.isFull()) { @@ -92,7 +96,15 @@ public class AdminSchemCommand extends CompositeCommand { if (args.get(0).equalsIgnoreCase("save")) { if (cb.isFull()) { if (args.size() == 2) { - return cb.save(user, args.get(1)); + // Check if file exists + File newFile = new File(schemFolder, args.get(1) + ".schem"); + if (newFile.exists()) { + user.sendMessage("commands.admin.schem.file-exists"); + this.askConfirmation(user, () -> cb.save(user, args.get(1))); + return false; + } else { + return cb.save(user, args.get(1)); + } } else { showHelp(this, user); return false; diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java index 99a09d220..837daa747 100644 --- a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java +++ b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java @@ -658,11 +658,11 @@ public class Clipboard { /** * Save the clipboard to a file * @param user - user who is copying - * @param string - filename + * @param newFile - filename * @return - true if successful, false if error */ - public boolean save(User user, String string) { - File file = new File(schemFolder, string); + public boolean save(User user, String newFile) { + File file = new File(schemFolder, newFile); try { getBlockConfig().save(file); } catch (IOException e) { From aa1ef9bcbd19cb735a790c2732496874aaad1c06 Mon Sep 17 00:00:00 2001 From: tastybento Date: Tue, 3 Jul 2018 17:51:01 -0700 Subject: [PATCH 14/14] Added new island and nether island schems Fixed bugs with schem pasting, especially empty chests. --- plugin.yml | 4 ++-- schems/island.schem | Bin 899 -> 1116 bytes schems/nether-island.schem | Bin 1778 -> 2823 bytes .../commands/admin/AdminSchemCommand.java | 2 -- .../bskyblock/island/builders/Clipboard.java | 6 ++++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugin.yml b/plugin.yml index 322e7155a..0e471f4ae 100755 --- a/plugin.yml +++ b/plugin.yml @@ -41,13 +41,13 @@ permissions: default: true bskyblock.island.lock: description: Allows island locking - default: false + default: true bskyblock.island.expel: description: Allows expelling of visitors default: true bskyblock.island.ban: description: Allows banning of visitors - default: false + default: true bskyblock.island.settings: description: Player can see server settings default: true diff --git a/schems/island.schem b/schems/island.schem index 71454161268b76f459ae4b2be037ff483472252a..55a0e2f58a3797592ce21b99ab4ddec9a46f0923 100644 GIT binary patch delta 1073 zcmV-11kU?|2iyn^P)h>@6aWYa2mlLxoV<{f%=D0~RXK=K zYQ=~J8V{*0izu5|DyEd|uKD!~2!xM$d!hC==?C5I^n1gbyzCCE?WyyPv9=~P9xoUR z&+mSR^=#7|Tkg!BSW9=-9XW0SuD#IfFiO^&;Fo_4{dI?h#}7XV{q$Cw;I+f7t~*P! ze~Mz(Bwqp;nqCA3PSm2pFBt2YKrMMqQ7(NuIa6&+8-&ONT+!XY9cLIBa*uuue{N)d!g zMUc7{*MxGEJR(b}g@t9NVHG1d;2f`Vf36Uhs`M2m=8vn1$N>>KAR-4u-6y=zr{9hD}AlQbEYw5U_j%#u7me6>) zlsmJgh2vS*(}zm0n^xbkdk+aDlpGdS1-jiyKaHz6EUL;Z#MSu;g?3xvn>|Rwr3$^F zm3-VYwuxk&efeE`J{u;H*d7Go;ds8h%vh`4%9f1X-*?#I_$(vEFU$=f9F{J<>TBPI=20oB{Z5Oe6+^)B+H~X`mLj$l}Eh& z;Ufq;jOVF&lho$LPodn6w$$xT$D_$0Pu6HVr}M|@!zkZS-e^Nj$6ico%_x;Nyo^*eO|@7OwL2P2mQy>`V_kz@7-fC)*Vhpg9~#jvl;Q>Jf45p^?@b^x7>z)nVB zCnM@kCM$$&jEHRv%!VCKe*~!$Qq{a%{5sXVODasNnv^1-as>n~5QHwR1Z)QZ+d<%} zK)`koupNZ#1tEJu$X*b-DiHD)g!}~|e?e8n&1|PPESwQ~>5NGKg-|;p7FH#m9}xt# zOHjK6?;-@{OHjUqqQ%u$IsDltbT=BNQiX`l%hXaWYB zfPp4ps3-8^uaA*w=v?l{-%guPKYr*>vS7E-@_bn)oc_$he*sWS2ME&Kfp*>l000&i r002-+0Rj{N6aWYa5C{MZedA2h+<|u90{{RP7L!v0Dh3h+000007l`!J delta 854 zcmV-c1F8Jn2!jU=P)h>@6aWYa2msQP*^vzwf2Ef}PuoBch41|p+fyzEWp`!_SmF=| zD@3F*iUU1V6*6FG6i6y?P{Xh9+SpMX_O+IBTg|Lzmf7#|Hn&g9yZLMIMX9bQ9u*6v z^7Zd5P-nx*w2b?n-i{9@y(Fm;1|lMvrR`xgh#L?`br{6O8TY-e`=DS- ze;Q3mqbX@LC5@-#d%iny+-yFIde>2%A!kOZ`!r7jbzJT`f#08i?~4pOGsYw5B^Z0j zu1hoE@{73Z(hPvY04NNA!T=}?fWjas41&TSC=7zaASeui!XPM&y?PBU2;pK{;bQF7 zqsj=R-S69VaRauyOTbxl7yg+xqOI zPC!Wnlte&DMchR?Sp{@K+pe9w<{+ zHv3fm7LDTZO%g?CNnMZjsTaoMe;k$fDcz65aAdF3)j{eGvQLMkcR3o42hQ^sXf;qw zhJ*3VW!%8)xPjL=o>X|Hx$X8Vf4e`hsX`C&_i-a0sQhJ>m7%BEB76PlbD%mu!eqV< ziwEb=P8B;(-!k>ET70edbhZ}+or<7SHUH!8x>hADWK#rfiauG>rqutvh@clWcR^pG z&%RW(ho(e@DYY3IE#>KJ$t121CWMGU-!fwwU576#tJz*`u3e+VNFVdNo< zUUiI2gpr9bG7*MaVW<^u^{Qhi7jE^cWB97$R_bA>9>$7c{E} zz*YdZ0HFmlFSn94_zt`cvP)i30@=AQ*1p@#8?-2k1P)h*<6aW+e g2nYxO(v#Ut@=AQ*1p@#8?-7$M1S$qO0{{R309vn$*8l(j diff --git a/schems/nether-island.schem b/schems/nether-island.schem index 968824f5c08d907d5d5056302217a36d4a4a2f1c..5cd7841c306f6639dbe566a0e569d8006b621577 100644 GIT binary patch delta 2778 zcmV<03MKXO4TlyDP)h>@6aWYa2mnBhccIwG83urpnIZ{HkpxcdP%_Y#2~M_HC>1D10NN$#X+7zu{pry6`s3T#sQyql z2vs;j6^>Aacc2RI!USGmLcH8OY+keD#Nq@rCbqO}5owFXa$yCWYm3`)DCQ&z!ywAB z`HfCS{Vy)a2Ht{IyalUx7gq7^DbKr?7JlSZI-QAsJ(^AW-XOC=Da`kza3KSllei3! z7(ihF4FCjEFa*K^fv`YenJc< zag>lGOs*ODH(u%dac{Hw7AL19qDT@^q#~&$rcM%5Cy6PN#1u(lDkM{3X&OUPLWko? zh049&!}5=KwMiqk2%gq)e<|2E?qr&~ERFioKbcLg`Zu0CHfPsggFlyXG_CXiQT!CV zCgoI1^Yc0Q?#01s{_3U*@DQ)FPSF@9sfR&^SGJv^8 zu)IrdO2pehwx?J=^rm%l_GAKeJTkcQ)>Sc1M{BQa=f+pM=#657RNlf}=Z3Vvt+$1%un40M>n(Cla3ezdIPpAGqE7U$^JJ97n z%UzYSOzdHqs!{O7e;thdJYtpgSLs5hGWVRGsz%%$J&j52xrhK8KgKNf`6OkZWs`=S zRu)J_J}FpA6f7kQmJ$U^iGroXn9Dq@j2u=Pg(-~!l}2GoqcEjWn9?XzX%wb3s+-az z;L?as&olNEQE${r!ZAJH5pcPAS?vnqd;9%cz5Dp_xc9QUfBP{1_W1a)`LF|j7;fU{ zNz%4GR!U>K(4U=LpI*4r+@CnaUnOeUpWylB+j5iXrn!YW9%)GJduND|7kSz zrn4l=61j5?g)^t*5T}>Emv|e`+_STtF!tNG`;>ZIbS%P!mKR;($25sBYpOp zc(n|kj(g{9e?9Eye|+!Z)<1b*=Tq-OJ+6QM<@^7pesp(x`StSl%V78;{63ma_{H?} z+xLq#_kUbJZeGLxj((`SKQ12m({18nGP<95zZq{Ii#JSke*G9f#haJq?EYo775p?r z2W3f9i1H+%KR;;k;Hnt3$yyIbr~Ez*6#Mh)<(t2An;rY%ey$kGjDd~Z{@Hqfvwl2z24KqGG1rC zt={|po0ZG#K3>JYzRyoKADB^9N?vJLnM$kD5Iui<;1F-(r|{)D?rmPSCpPzS&x@0P zSG!3pe}m`v*Z-78tC20kVh^X0#k%g$1Z!kNT_YRn8f&6;q2sM=X)PG#krP?*Jf_Jy z(4kfk&6O3!aTM8%D(R?w>%hdT0vi?sfEpH^wyG591`MEaFHSSA=OpA-7-(s+U~XGM zm~Q(AJe-G|3tQF}us1{Fd~)HA+^O&7{`W0qfA!v_tlqzr)wRC1)VylAJ=Jh~s^Ruj z!|kbt+f$A8pBn2wHQ0Y@tpC(l|EaP5Q=|Q-#`;g)rTdks+W=%Mj3(a*BYpB||j%C?K3&w94`mIE#hg ze?e?Hwj>rKLRxcSb1M$)kl1_?hfz&_jC#yYuTOH{&~(O3#ljimsyvCuNR(Z>!!x~MQge^j{Gm>F=}F3y14zM(Z>P^n4VFC)kfjrk*; z{E=2~kaKiJtA=CWD?Xs=i`xdfMC@HgQ&p9EENGWUMQH1{=_#5uzb&UsDLW8hLM%H@ zT2>}4Z6`kolXMYEYBMJH_1dXh34D@~*@1FFkg{#;K)E1jStn>&C$+M^YnwA0e^}5B z0;~oEE%^j3`J}cYs3V|HXEHNTR|#4-30gM^_Ch^FAi-)bouzStg_EFFk)U;s)aqR2 zgEhi;FtFH>Bih(9zDinv{pLx3Fc{_Aa0l)Ue-FKjgl~nNuqb#A()Z|e=l`G`w}$O}$2r8Id+W~p zPc!rFQTmjfBO)pr2qXVyGW9)oXI79|Hsxxb%MMa29Hdq_NUd;?T4C&fv^cd|@>T~N zw2C-D6>(7MbWqW9Ql$W+2P=((D2=g$(ZiI;L6yismB>Mr$RNNHV*Y=^fBq~s=KWbr zYaA%Yf!0XSVAqg)kR%i#2}MXk5t2}ZBorYDtr6iZ&1tP!0>5%9Z9MEgb)wA9_T3x4 zbs~))J5ka6wG;U}pF5?W+)FTfs06czHuj@$;e%OB5f)Q~#S~$&v4fAd%JRa_b7ln@ zPHPM=Ue9XWDsL_^xWF)ke;cgEjeKW3GXZg9HCoh02GYXVfo&;vM4`%R%+SPXW%PA3 z@X%Q;XB+JMC5s_B&5)dCNKP{(rx}vd49RH*<}|D2bj=FnbG2H5f>(IMvy(f;ex}%& z2{i5s=wLwtt%wzef?G`J&{8bm)?5YiSUB2t7_IIK)L&#Jl{Wbce>_{BG9I>r<&Gn~ z=195Y2(LN9Yo3<8lD)c6v@;l3H8{c`jxdNL4B`kwj2)PzK%yv+D2i0xfbof%zSZpD z`~@<9fhdST;v>-b(8{(cr~_ubb=fcJfc-ONKqB#xNPHv`ADPAnVu^Y;kE7K~_;|ei zhVR delta 1725 zcmV;u215CV7V-@ZP)h>@6aWYa2mno?*^vz&f0|8m+DH(F@A(zllMgGq&`2YVsLDZr zf?0#)NOD}xMMbdIX2FnvoY?;Ls}B(9t6x`9srV$On;uQi)9;l*g%C3O;3W%?O_zc8nRD1^3&%pW_SU&^nXJGvd zf2^N@^|Si={lE%Fu48$3;n@0O6;9+NDm95JoAS9{n!~*rhrZwl-S`Rbu7-CSoMr*S-;Jx2HE$$0XefqUze#=BCyd5)4HE*q6hOswI= z$}ClghMx7s9%m*JAWj3sX@EEl5T^m+5Fic#;&p(Ib&x}PIHZR|dN`zqLwb0de@=zB zi5&RJurBMBrS$B9=VtNs6b+*Z4ZQ|UfktNH&0i9gw3kFFGaD^2MI~n0q!B^QN`{U% zQl~N2X^eFmW1YrWr!mgVYWs~N$aM(0PD8Fk$aM(04k6be??&Z?0Vi&Xrhfe|&!VCvfi{ z?k3+ScV7pix7o`$@cC8He}1{za`)|K5x>s<9>0l)pH~aMyh}p(<4525FN^l^c*3NQ z*)F1G6t7p|<9f4=iWHqhe@Rn{_K>K5K55b5`Z#I+)*Oxd{4q_G_Un56#h*1L>fv#^ zjf?!8gm^`PD+wyfh@Hgg&>auLku!9I+7wzb!%2EJ@?0nES>7O-rHIH+iRjsbkdzo+ z96{y7eKd5!YqxX^iPACTxZdsiIVHh zU%O9dXU7+Y%;_d0bD(+*BkeAg4sm!Jt&bl@`{Rc}_iYB6ZED+9_1NB}( zK;AQtrVs}Q^3{!?f6*5-`hrGZ(C7;qeF4!I5PdZasTGx@s?|qjfWTqnmQV*H{W}wuj9!)X!9;Qsb9W`m8F=?U6%!M1nKg4!+$?Lx;$Uyv^uuaU0h_RZa}R1?lANm5)^6P`R8`xm&y(;0J*(g0djjgREZr3K;prgT@E2=7IqHgB3QFV962Cdc0On+ z0GOQ%AcnQ5e@)?{$c%z2Gq*#f)Q~J^L#Z*@VAqK7fLR4Fs{m#dz^nq8RRFU}?Z}z9 zy)b*9VSCx=_WShLD!LC24{>4trnl3%XgPgNgihsV_W5c0;zZNUw^w@=&*ORWjJkh; zm{|NY&>;VYs&_j1_3O9Ek_Yzhuqa~ODT3L1{>@|`dJ;KCWm&dV30C~C}W5+hA3l*GKMH)byX)N!@sh}c9MgVU~sPfNx@KM z^51C^f4d6ov}&uM7*wFzDkv5e6pIQ3Peq`q2s9OerXr4V2VxN#NRkGUq=6)9nPL!2 z(CU&=bD*=Np)6^r95s|i4W}`!SN`sL?TxLk< ih.setItem(Integer.valueOf(i), (ItemStack)inv.get(i))); + if (config.isConfigurationSection("inventory")) { + ConfigurationSection inv = config.getConfigurationSection("inventory"); + inv.getKeys(false).forEach(i -> ih.setItem(Integer.valueOf(i), (ItemStack)inv.get(i))); + } } // Entities