From fdb2441b1a5a1134e670f4322fc3d5a25d4f6d00 Mon Sep 17 00:00:00 2001 From: dfsek Date: Wed, 10 Mar 2021 15:28:50 -0700 Subject: [PATCH] export command --- .../api/command/TerraCommandManager.java | 2 +- .../terra/api/platform/block/BlockData.java | 2 + .../structure/StructureExportCommand.java | 98 ++++++++++++++++++- .../world/block/data/BukkitBlockData.java | 6 ++ .../fabric/world/block/FabricBlockData.java | 6 ++ .../java/com/dfsek/terra/platform/Data.java | 5 + .../world/block/data/SpongeBlockData.java | 5 + 7 files changed, 121 insertions(+), 3 deletions(-) diff --git a/common/src/main/java/com/dfsek/terra/api/command/TerraCommandManager.java b/common/src/main/java/com/dfsek/terra/api/command/TerraCommandManager.java index b12f4ea78..d76c3a83f 100644 --- a/common/src/main/java/com/dfsek/terra/api/command/TerraCommandManager.java +++ b/common/src/main/java/com/dfsek/terra/api/command/TerraCommandManager.java @@ -176,7 +176,7 @@ public class TerraCommandManager implements CommandManager { try { template.execute(state.getSender()); } catch(Throwable e) { - throw new ExecutionException("Failed to execute command: ", e); + throw new ExecutionException("Failed to execute command: " + e.getMessage(), e); } } catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | InjectionException e) { throw new MalformedCommandException("Unable to reflectively instantiate command: ", e); diff --git a/common/src/main/java/com/dfsek/terra/api/platform/block/BlockData.java b/common/src/main/java/com/dfsek/terra/api/platform/block/BlockData.java index fc7df1172..3082a2184 100644 --- a/common/src/main/java/com/dfsek/terra/api/platform/block/BlockData.java +++ b/common/src/main/java/com/dfsek/terra/api/platform/block/BlockData.java @@ -13,4 +13,6 @@ public interface BlockData extends Cloneable, Handle { String getAsString(); boolean isAir(); + + boolean isStructureVoid(); } diff --git a/common/src/main/java/com/dfsek/terra/commands/structure/StructureExportCommand.java b/common/src/main/java/com/dfsek/terra/commands/structure/StructureExportCommand.java index 499493cb8..d596ff3dc 100644 --- a/common/src/main/java/com/dfsek/terra/commands/structure/StructureExportCommand.java +++ b/common/src/main/java/com/dfsek/terra/commands/structure/StructureExportCommand.java @@ -1,13 +1,107 @@ package com.dfsek.terra.commands.structure; +import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.command.CommandTemplate; +import com.dfsek.terra.api.command.annotation.Argument; import com.dfsek.terra.api.command.annotation.Command; +import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget; +import com.dfsek.terra.api.injection.annotations.Inject; +import com.dfsek.terra.api.math.vector.Location; import com.dfsek.terra.api.platform.CommandSender; +import com.dfsek.terra.api.platform.block.Block; +import com.dfsek.terra.api.platform.block.BlockData; +import com.dfsek.terra.api.platform.block.state.BlockState; +import com.dfsek.terra.api.platform.block.state.Sign; +import com.dfsek.terra.api.platform.entity.Player; +import com.dfsek.terra.api.util.generic.pair.Pair; -@Command +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +@Command( + arguments = { + @Argument( + value = "id" + ) + } +) public class StructureExportCommand implements CommandTemplate { + @Inject + private TerraPlugin main; + + @ArgumentTarget("id") + private String id; + @Override public void execute(CommandSender sender) { - System.out.println("export command"); + Player player = (Player) sender; + + Pair l = main.getWorldHandle().getSelectedLocation(player); + + Location l1 = l.getLeft(); + Location l2 = l.getRight(); + + StringBuilder scriptBuilder = new StringBuilder("id \"" + id + "\";\nnum y = 0;\n"); + + int centerX = 0; + int centerY = 0; + int centerZ = 0; + + for(int x = l1.getBlockX(); x <= l2.getBlockX(); x++) { + for(int y = l1.getBlockY(); y <= l2.getBlockY(); y++) { + for(int z = l1.getBlockZ(); z <= l2.getBlockZ(); z++) { + Block block = new Location(l1.getWorld(), x, y, z).getBlock(); + BlockState state = block.getState(); + if(state instanceof Sign) { + Sign sign = (Sign) state; + if(sign.getLine(0).equals("[TERRA]") && sign.getLine(1).equals("[CENTER]")) { + centerX = x - l1.getBlockX(); + centerY = y - l1.getBlockY(); + centerZ = z - l1.getBlockZ(); + } + } + } + } + } + + for(int x = l1.getBlockX(); x <= l2.getBlockX(); x++) { + for(int y = l1.getBlockY(); y <= l2.getBlockY(); y++) { + for(int z = l1.getBlockZ(); z <= l2.getBlockZ(); z++) { + + Block block = new Location(l1.getWorld(), x, y, z).getBlock(); + BlockData data = block.getBlockData(); + if(block.getBlockData().isStructureVoid()) continue; + BlockState state = block.getState(); + if(state instanceof Sign) { + Sign sign = (Sign) state; + if(sign.getLine(0).equals("[TERRA]")) { + data = main.getWorldHandle().createBlockData(sign.getLine(2) + sign.getLine(3)); + } + } + if(!data.isStructureVoid()) { + scriptBuilder.append("block(").append(x - l1.getBlockX() - centerX).append(", y + ").append(y - l1.getBlockY() - centerY).append(", ").append(z - l1.getBlockZ() - centerZ).append(", ") + .append("\""); + scriptBuilder.append(data.getAsString()).append("\");\n"); + } + } + } + } + + File file = new File(main.getDataFolder() + File.separator + "export" + File.separator + "structures", id + ".tesf"); + try { + file.getParentFile().mkdirs(); + file.createNewFile(); + } catch(IOException e) { + e.printStackTrace(); + } + try(BufferedWriter writer = new BufferedWriter(new FileWriter(file))) { + writer.write(scriptBuilder.toString()); + } catch(IOException e) { + e.printStackTrace(); + } + + sender.sendMessage("Exported structure to " + file.getAbsolutePath()); } } diff --git a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/data/BukkitBlockData.java b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/data/BukkitBlockData.java index a742d0549..e0dffe72b 100644 --- a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/data/BukkitBlockData.java +++ b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/data/BukkitBlockData.java @@ -4,6 +4,7 @@ import com.dfsek.terra.api.platform.block.BlockData; import com.dfsek.terra.api.platform.block.BlockType; import com.dfsek.terra.bukkit.TerraBukkitPlugin; import com.dfsek.terra.bukkit.world.BukkitAdapter; +import org.bukkit.Material; import org.bukkit.block.data.AnaloguePowerable; import org.bukkit.block.data.Directional; import org.bukkit.block.data.MultipleFacing; @@ -81,4 +82,9 @@ public class BukkitBlockData implements BlockData { public boolean isAir() { return delegate.getMaterial().isAir(); } + + @Override + public boolean isStructureVoid() { + return delegate.getMaterial() == Material.STRUCTURE_VOID; + } } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/FabricBlockData.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/FabricBlockData.java index e2608cb2c..2467e992a 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/FabricBlockData.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/FabricBlockData.java @@ -4,6 +4,7 @@ import com.dfsek.terra.api.platform.block.BlockData; import com.dfsek.terra.api.platform.block.BlockType; import com.dfsek.terra.fabric.world.FabricAdapter; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.state.State; import net.minecraft.util.registry.Registry; @@ -51,6 +52,11 @@ public class FabricBlockData implements BlockData { return delegate.isAir(); } + @Override + public boolean isStructureVoid() { + return delegate.getBlock() == Blocks.STRUCTURE_VOID; + } + @Override public BlockState getHandle() { return delegate; diff --git a/platforms/region/src/main/java/com/dfsek/terra/platform/Data.java b/platforms/region/src/main/java/com/dfsek/terra/platform/Data.java index 98c3ee0ec..f1c845ab0 100644 --- a/platforms/region/src/main/java/com/dfsek/terra/platform/Data.java +++ b/platforms/region/src/main/java/com/dfsek/terra/platform/Data.java @@ -52,6 +52,11 @@ public class Data implements BlockData, BlockType { return noProp.equals("minecraft:air"); } + @Override + public boolean isStructureVoid() { + return false; + } + @Override public BlockData clone() { diff --git a/platforms/sponge/src/main/java/com/dfsek/terra/sponge/world/block/data/SpongeBlockData.java b/platforms/sponge/src/main/java/com/dfsek/terra/sponge/world/block/data/SpongeBlockData.java index 9dc5dd3bd..eb68b9030 100644 --- a/platforms/sponge/src/main/java/com/dfsek/terra/sponge/world/block/data/SpongeBlockData.java +++ b/platforms/sponge/src/main/java/com/dfsek/terra/sponge/world/block/data/SpongeBlockData.java @@ -40,4 +40,9 @@ public class SpongeBlockData implements BlockData { public boolean isAir() { return false; } + + @Override + public boolean isStructureVoid() { + return false; + } }