diff --git a/api/src/main/java/net/islandearth/rpgregions/regenerate/Regenerate.java b/api/src/main/java/net/islandearth/rpgregions/regenerate/Regenerate.java index 10169a1..ae6f15c 100644 --- a/api/src/main/java/net/islandearth/rpgregions/regenerate/Regenerate.java +++ b/api/src/main/java/net/islandearth/rpgregions/regenerate/Regenerate.java @@ -1,11 +1,14 @@ package net.islandearth.rpgregions.regenerate; import net.islandearth.rpgregions.regenerate.entity.RegeneratingEntity; +import org.bukkit.Location; import java.util.List; public class Regenerate { + private String schematicName; + private Location origin; private final int regenerateInterval; private final boolean loadChunks; private final List regeneratingEntities; @@ -27,4 +30,20 @@ public class Regenerate { public List getRegeneratingEntities() { return regeneratingEntities; } + + public String getSchematicName() { + return schematicName; + } + + public void setSchematicName(String schematicName) { + this.schematicName = schematicName; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } } diff --git a/rpgregions/src/main/java/net/islandearth/rpgregions/RPGRegions.java b/rpgregions/src/main/java/net/islandearth/rpgregions/RPGRegions.java index 7052cbb..55f4d2d 100644 --- a/rpgregions/src/main/java/net/islandearth/rpgregions/RPGRegions.java +++ b/rpgregions/src/main/java/net/islandearth/rpgregions/RPGRegions.java @@ -39,8 +39,11 @@ import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.potion.PotionEffect; import org.jetbrains.annotations.NotNull; +import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; public final class RPGRegions extends JavaPlugin implements RPGRegionsAPI, LanguagyPluginHook { @@ -189,6 +192,14 @@ public final class RPGRegions extends JavaPlugin implements RPGRegionsAPI, Langu private void registerCommands() { PaperCommandManager manager = new PaperCommandManager(this); manager.getCommandCompletions().registerAsyncCompletion("regions", context -> ImmutableList.copyOf(getManagers().getRegionsCache().getConfiguredRegions().keySet())); + manager.getCommandCompletions().registerAsyncCompletion("schematics", context -> { + File schematicFolder = new File("plugins/WorldEdit/schematics/"); + List files = new ArrayList<>(); + for (File file : schematicFolder.listFiles()) { + files.add(file.getName()); + } + return files; + }); manager.getCommandContexts().registerContext(ConfiguredRegion.class, context -> { String id = context.popFirstArg(); for (ConfiguredRegion region : plugin.getManagers().getRegionsCache().getConfiguredRegions().values()) { diff --git a/rpgregions/src/main/java/net/islandearth/rpgregions/commands/RPGRegionsCommand.java b/rpgregions/src/main/java/net/islandearth/rpgregions/commands/RPGRegionsCommand.java index cc8d33d..e45b51b 100644 --- a/rpgregions/src/main/java/net/islandearth/rpgregions/commands/RPGRegionsCommand.java +++ b/rpgregions/src/main/java/net/islandearth/rpgregions/commands/RPGRegionsCommand.java @@ -7,9 +7,11 @@ import co.aikar.commands.annotation.CommandPermission; import co.aikar.commands.annotation.Default; import co.aikar.commands.annotation.Subcommand; import net.islandearth.rpgregions.RPGRegions; +import net.islandearth.rpgregions.api.integrations.IntegrationType; import net.islandearth.rpgregions.gui.DiscoveryGUI; import net.islandearth.rpgregions.gui.EditorGUI; import net.islandearth.rpgregions.managers.data.region.ConfiguredRegion; +import net.islandearth.rpgregions.regenerate.Regenerate; import net.islandearth.rpgregions.rewards.ItemReward; import net.islandearth.rpgregions.utils.RegenUtils; import net.islandearth.rpgregions.utils.StringUtils; @@ -25,11 +27,14 @@ import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; +import java.util.List; +import java.util.UUID; @CommandAlias("rpgregions") public class RPGRegionsCommand extends BaseCommand { private final RPGRegions plugin; + private List regenerateConfirm = new ArrayList<>(); public RPGRegionsCommand(RPGRegions plugin) { this.plugin = plugin; @@ -244,15 +249,58 @@ public class RPGRegionsCommand extends BaseCommand { @Subcommand("regenerate|regen") @CommandPermission("rpgregions.regenerate") @CommandCompletion("@regions") - public void onRegenerate(CommandSender sender, ConfiguredRegion configuredRegion) { - sender.sendMessage(ChatColor.GREEN + "Regenerating region..."); - long startTime = System.currentTimeMillis(); - boolean done = RegenUtils.regenerate(configuredRegion); - if (!done) { - sender.sendMessage(ChatColor.RED + "Unable to regenerate region. Check console for details."); + public void onRegenerate(Player player, ConfiguredRegion configuredRegion) { + IntegrationType integrationType = IntegrationType.valueOf(plugin.getConfig().getString("settings.integration.name").toUpperCase()); + if (integrationType != IntegrationType.WORLDGUARD) { + player.sendMessage(ChatColor.RED + "Regeneration only supports WorldGuard integrations."); + return; + } + + if (!regenerateConfirm.contains(player.getUniqueId())) { + regenerateConfirm.add(player.getUniqueId()); + player.sendMessage(ChatColor.YELLOW + "Run /rpgregions regenerate " + configuredRegion.getId() + " again to confirm. Only use if you know what you are doing!"); + player.sendMessage(ChatColor.RED + "" + ChatColor.ITALIC + "" + ChatColor.BOLD + "The regenerate configuration is very dangerous and can delete world sections if used wrongly."); + } else { + regenerateConfirm.remove(player.getUniqueId()); + player.sendMessage(ChatColor.GREEN + "Regenerating region..."); + long startTime = System.currentTimeMillis(); + boolean done = RegenUtils.regenerate(configuredRegion); + if (!done) { + player.sendMessage(ChatColor.RED + "Unable to regenerate region. Check console for details."); + } + long endTime = System.currentTimeMillis(); + long totalTime = endTime - startTime; + player.sendMessage(ChatColor.GREEN + "Done! (" + totalTime + "ms)"); + } + } + + @Subcommand("setschematic") + @CommandPermission("rpgregions.setschematic") + @CommandCompletion("@regions @schematics @nothing") + public void onAddSchematic(Player player, ConfiguredRegion configuredRegion, String schematicName) { + IntegrationType integrationType = IntegrationType.valueOf(plugin.getConfig().getString("settings.integration.name").toUpperCase()); + if (integrationType != IntegrationType.WORLDGUARD) { + player.sendMessage(ChatColor.RED + "Regeneration only supports WorldGuard integrations."); + return; + } + + if (configuredRegion != null) { + if (!regenerateConfirm.contains(player.getUniqueId())) { + regenerateConfirm.add(player.getUniqueId()); + player.sendMessage(ChatColor.YELLOW + "Run /rpgregions addschematic " + schematicName + " again to confirm. Only use if you know what you are doing!"); + player.sendMessage(ChatColor.RED + "MAKE SURE YOU ARE STANDING WHERE YOU CREATED THE SCHEMATIC ORIGINALLY (//copy, //schematic save), OTHERWISE IT WILL NOT PASTE CORRECTLY."); + player.sendMessage(ChatColor.RED + "" + ChatColor.ITALIC + "" + ChatColor.BOLD + "The regenerate configuration is very dangerous and can delete world sections if used wrongly."); + } else { + regenerateConfirm.remove(player.getUniqueId()); + Regenerate regenerate = configuredRegion.getRegenerate(); + if (regenerate == null) regenerate = new Regenerate(Integer.MAX_VALUE, false, new ArrayList<>()); + regenerate.setSchematicName(schematicName); + regenerate.setOrigin(player.getLocation()); + configuredRegion.setRegenerate(regenerate); + player.sendMessage(ChatColor.GREEN + "This region has had a regenerate section added, and schematicName set to " + schematicName + " and origin set to " + player.getLocation().toString() + "."); + player.sendMessage(ChatColor.YELLOW + "Run /rpgregions save and " + ChatColor.BOLD + "CONFIGURE BEFORE RELOADING OR RESTARTING THE SERVER."); + player.sendMessage(ChatColor.RED + "" + ChatColor.ITALIC + "" + ChatColor.BOLD + "The regenerate configuration is very dangerous and can delete world sections if used wrongly."); + } } - long endTime = System.currentTimeMillis(); - long totalTime = endTime - startTime; - sender.sendMessage(ChatColor.GREEN + "Done! (" + totalTime + "ms)"); } } diff --git a/rpgregions/src/main/java/net/islandearth/rpgregions/managers/RPGRegionsManagers.java b/rpgregions/src/main/java/net/islandearth/rpgregions/managers/RPGRegionsManagers.java index 10434af..795ea44 100644 --- a/rpgregions/src/main/java/net/islandearth/rpgregions/managers/RPGRegionsManagers.java +++ b/rpgregions/src/main/java/net/islandearth/rpgregions/managers/RPGRegionsManagers.java @@ -90,7 +90,7 @@ public class RPGRegionsManagers { ConfiguredRegion configuredRegion = new ConfiguredRegion(null, "exampleconfig", "ExampleConfig", rewards, effects, XSound.AMBIENT_UNDERWATER_EXIT.parseSound(), XMaterial.WOODEN_AXE); - configuredRegion.setRegenerate(new Regenerate(5000, + configuredRegion.setRegenerate(new Regenerate(50000, false, Collections.singletonList( new RegeneratingEntity(EntityType.SHULKER, Arrays.asList( diff --git a/rpgregions/src/main/java/net/islandearth/rpgregions/utils/RegenUtils.java b/rpgregions/src/main/java/net/islandearth/rpgregions/utils/RegenUtils.java index 2322e0a..4216864 100644 --- a/rpgregions/src/main/java/net/islandearth/rpgregions/utils/RegenUtils.java +++ b/rpgregions/src/main/java/net/islandearth/rpgregions/utils/RegenUtils.java @@ -2,8 +2,16 @@ package net.islandearth.rpgregions.utils; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; +import com.sk89q.worldedit.function.operation.Operation; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.world.World; import com.sk89q.worldguard.WorldGuard; import com.sk89q.worldguard.protection.regions.ProtectedRegion; @@ -17,6 +25,9 @@ import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.plugin.java.JavaPlugin; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; @@ -39,6 +50,27 @@ public class RegenUtils { World world = BukkitAdapter.adapt(region.getWorld()); EditSession session = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, Integer.MAX_VALUE); + try { + if (regenerate.getSchematicName() != null && regenerate.getOrigin() != null) { + BlockVector3 position = BlockVector3.at(regenerate.getOrigin().getX(), regenerate.getOrigin().getY(), regenerate.getOrigin().getZ()); + File schematic = new File("plugins/WorldEdit/schematics/" + regenerate.getSchematicName()); + ClipboardFormat format = ClipboardFormats.findByFile(schematic); + EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1); + Clipboard clipboard = format.getReader(new FileInputStream(schematic)).read(); + ClipboardHolder clipboardHolder = new ClipboardHolder(clipboard); + Operation operation = clipboardHolder.createPaste(editSession) + .to(position) + .ignoreAirBlocks(false) + .build(); + Operations.complete(operation); + editSession.flushSession(); + return true; + } + } catch (IOException | WorldEditException e) { + e.printStackTrace(); + return false; + } + boolean result = world.regenerate(new CuboidRegion(world, protectedRegion.getMinimumPoint(), protectedRegion.getMaximumPoint()), session); if (!result) { plugin.getLogger().severe("Could not regenerate region " + region.getId() + "!");