From 1844d4dba7350117f7b446b7ed9f1c232072e821 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Sat, 23 Nov 2019 04:31:48 +0000 Subject: [PATCH] Various major Add regen Add //history [find|restore|rollback|summary|clear] - history commands are interactable - inspect brush info is interactable Commands are now logged to a searchable database Fix some cases of id/ordinal mismatch --- .../com/boydti/fawe/bukkit/BukkitCommand.java | 56 --- .../adapter/mc1_14/BukkitGetBlocks_1_14.java | 39 +- .../bukkit/filter/GriefPreventionFilter.java | 7 +- .../fawe/bukkit/filter/WorldGuardFilter.java | 24 +- .../bukkit/BukkitBlockCommandSender.java | 21 - .../worldedit/bukkit/BukkitCommandSender.java | 21 - .../sk89q/worldedit/bukkit/BukkitWorld.java | 6 +- .../bukkit/adapter/BukkitImplAdapter.java | 6 + .../adapter/impl/FAWE_Spigot_v1_14_R4.java | 67 +++ .../com/boydti/fawe/command/Rollback.java | 184 --------- .../java/com/boydti/fawe/config/Caption.java | 9 + .../fawe/database/RollbackDatabase.java | 391 ++++++++++-------- .../rollback/RollbackOptimizedHistory.java | 55 ++- .../fawe/object/brush/BrushSettings.java | 10 + .../fawe/object/brush/InspectBrush.java | 83 ++-- .../cfi/HeightMapMCAGenerator.java | 3 +- .../object/change/MutableBlockChange.java | 8 +- .../changeset/AbstractDelegateChangeSet.java | 4 - .../object/changeset/DiskStorageHistory.java | 91 ++-- .../fawe/object/changeset/FaweChangeSet.java | 14 +- .../object/changeset/FaweStreamChangeSet.java | 22 +- .../clipboard/ResizableClipboardBuilder.java | 2 +- .../object/collection/SummedColorTable.java | 9 +- .../fawe/object/collection/YieldIterable.java | 71 ++++ .../fawe/object/task/AsyncNotifyQueue.java | 81 ++-- .../object/task/SimpleAsyncNotifyQueue.java | 49 --- .../boydti/fawe/util/EditSessionBuilder.java | 12 +- .../java/com/boydti/fawe/util/MainUtil.java | 10 +- .../java/com/sk89q/worldedit/EditSession.java | 2 - .../com/sk89q/worldedit/LocalSession.java | 5 + .../worldedit/command/HistoryCommands.java | 175 +------- .../worldedit/command/HistorySubCommands.java | 376 +++++++++++++++++ .../worldedit/command/SchematicCommands.java | 7 +- .../worldedit/command/SelectionCommands.java | 10 +- .../command/SuperPickaxeCommands.java | 1 - .../worldedit/command/tool/AreaPickaxe.java | 2 +- .../command/tool/BlockDataCyler.java | 2 +- .../worldedit/command/tool/BlockReplacer.java | 2 +- .../worldedit/command/tool/BrushTool.java | 7 +- .../command/tool/FloatingTreeRemover.java | 2 +- .../worldedit/command/tool/FloodFillTool.java | 2 +- .../command/tool/LongRangeBuildTool.java | 4 +- .../command/tool/RecursivePickaxe.java | 2 +- .../factory/parser/DefaultBlockParser.java | 6 +- .../platform/AbstractNonPlayerActor.java | 6 +- .../platform/AbstractPlayerActor.java | 9 +- .../worldedit/extension/platform/Actor.java | 6 +- .../platform/PlatformCommandManager.java | 20 +- .../platform/binding/ConsumeBindings.java | 37 ++ .../platform/binding/ProvideBindings.java | 42 +- .../internal/annotation/AllowedRegion.java | 16 + .../worldedit/internal/annotation/Time.java | 14 + .../sk89q/worldedit/util/Identifiable.java | 2 + .../formatting/component/PaginationBox.java | 23 +- .../util/translation/TranslationManager.java | 4 + .../src/main/resources/lang/strings.json | 21 +- 56 files changed, 1236 insertions(+), 924 deletions(-) delete mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/BukkitCommand.java delete mode 100644 worldedit-core/src/main/java/com/boydti/fawe/command/Rollback.java create mode 100644 worldedit-core/src/main/java/com/boydti/fawe/object/collection/YieldIterable.java delete mode 100644 worldedit-core/src/main/java/com/boydti/fawe/object/task/SimpleAsyncNotifyQueue.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/command/HistorySubCommands.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/internal/annotation/AllowedRegion.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/internal/annotation/Time.java diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/BukkitCommand.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/BukkitCommand.java deleted file mode 100644 index ce2b4efb7..000000000 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/BukkitCommand.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.boydti.fawe.bukkit; - -import com.sk89q.worldedit.util.formatting.text.TextComponent; -import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; -import com.boydti.fawe.object.FaweCommand; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.BukkitBlockCommandSender; -import com.sk89q.worldedit.bukkit.BukkitCommandSender; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.extension.platform.Actor; -import org.bukkit.command.BlockCommandSender; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - -public class BukkitCommand implements CommandExecutor { - - private final FaweCommand cmd; - - public BukkitCommand(FaweCommand cmd) { - this.cmd = cmd; - } - - @Override - public boolean onCommand(@NotNull CommandSender sender, Command cmd, String label, String[] args) { - final Actor plr = wrapCommandSender(sender); - if (!sender.hasPermission(this.cmd.getPerm()) && !sender.isOp()) { - plr.printError(TranslatableComponent.of("fawe.error.no.perm", TextComponent.of(this.cmd.getPerm()))); - return true; - } - this.cmd.executeSafe(plr, args); - return true; - } - - /** - * Used to wrap a Bukkit Player as a WorldEdit Player. - * - * @param player a player - * @return a wrapped player - */ - public com.sk89q.worldedit.bukkit.BukkitPlayer wrapPlayer(Player player) { - return BukkitAdapter.adapt(player); - } - - public Actor wrapCommandSender(CommandSender sender) { - if (sender instanceof Player) { - return wrapPlayer((Player) sender); - } else if (sender instanceof BlockCommandSender) { - return new BukkitBlockCommandSender(WorldEditPlugin.getInstance(), (BlockCommandSender) sender); - } - - return new BukkitCommandSender(WorldEditPlugin.getInstance(), sender); - } -} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java index 86e443c09..4544b5869 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java @@ -3,6 +3,7 @@ package com.boydti.fawe.bukkit.adapter.mc1_14; import static com.google.common.base.Preconditions.checkNotNull; import static org.slf4j.LoggerFactory.getLogger; +import com.bekvon.bukkit.residence.commands.set; import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkSet; @@ -67,26 +68,18 @@ import org.jetbrains.annotations.NotNull; public class BukkitGetBlocks_1_14 extends CharGetBlocks { public ChunkSection[] sections; public Chunk nmsChunk; - public CraftWorld world; + public WorldServer world; public int X, Z; -// private boolean forceLoad; - public BukkitGetBlocks_1_14(World world, int X, int Z, boolean forceLoad) { - this.world = (CraftWorld) world; - this.X = X; - this.Z = Z; -// if (forceLoad) { -// this.world.getHandle().setForceLoaded(X, Z, this.forceLoad = true); -// } + public BukkitGetBlocks_1_14(World world, int X, int Z) { + this(((CraftWorld) world).getHandle(), X, Z); } -// @Override -// protected void finalize() { -// if (forceLoad) { -// this.world.getHandle().setForceLoaded(X, Z, forceLoad = false); -// } -// } - + public BukkitGetBlocks_1_14(WorldServer world, int X, int Z) { + this.world = world; + this.X = X; + this.Z = Z; + } public int getX() { return X; @@ -133,14 +126,16 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks { @Override public CompoundTag getEntity(UUID uuid) { - org.bukkit.entity.Entity bukkitEnt = world.getEntity(uuid); - if (bukkitEnt != null) { + Entity entity = world.getEntity(uuid); + if (entity != null) { + org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity(); return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); } for (List entry : getChunk().getEntitySlices()) { if (entry != null) { - for (Entity entity : entry) { - if (uuid.equals(entity.getUniqueID())) { + for (Entity ent : entry) { + if (uuid.equals(ent.getUniqueID())) { + org.bukkit.entity.Entity bukkitEnt = ent.getBukkitEntity(); return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); } } @@ -235,7 +230,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks { @Override public > T call(IChunkSet set, Runnable finalizer) { try { - WorldServer nmsWorld = world.getHandle(); + WorldServer nmsWorld = world; Chunk nmsChunk = BukkitAdapter_1_14.ensureLoaded(nmsWorld, X, Z); // Remove existing tiles @@ -633,7 +628,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks { synchronized (this) { tmp = nmsChunk; if (tmp == null) { - nmsChunk = tmp = BukkitAdapter_1_14.ensureLoaded(this.world.getHandle(), X, Z); + nmsChunk = tmp = BukkitAdapter_1_14.ensureLoaded(this.world, X, Z); } } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/filter/GriefPreventionFilter.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/filter/GriefPreventionFilter.java index 30de5ffa0..7b16a5e18 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/filter/GriefPreventionFilter.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/filter/GriefPreventionFilter.java @@ -10,6 +10,7 @@ import org.bukkit.World; import java.util.ArrayDeque; import java.util.Collection; +import java.util.function.Supplier; import static com.google.common.base.Preconditions.checkNotNull; @@ -19,10 +20,10 @@ public class GriefPreventionFilter extends CuboidRegionFilter { public GriefPreventionFilter(World world) { checkNotNull(world); - this.claims = TaskManager.IMP.sync(new RunnableVal>() { + this.claims = TaskManager.IMP.sync(new Supplier>() { @Override - public void run(Collection claims) { - this.value = new ArrayDeque<>(GriefPrevention.instance.dataStore.getClaims()); + public Collection get() { + return new ArrayDeque<>(GriefPrevention.instance.dataStore.getClaims()); } }); this.world = world; diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/filter/WorldGuardFilter.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/filter/WorldGuardFilter.java index 39234c0f9..ac1dea0a5 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/filter/WorldGuardFilter.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/filter/WorldGuardFilter.java @@ -3,6 +3,7 @@ package com.boydti.fawe.bukkit.filter; import static com.google.common.base.Preconditions.checkNotNull; import static org.slf4j.LoggerFactory.getLogger; +import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweAPI; import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.regions.general.CuboidRegionFilter; @@ -26,20 +27,17 @@ public class WorldGuardFilter extends CuboidRegionFilter { } @Override public void calculateRegions() { - TaskManager.IMP.sync(new RunnableVal() { - @Override - public void run(Object value) { - WorldGuardFilter.this.manager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(FaweAPI.getWorld(world.getName())); - for (ProtectedRegion region : manager.getRegions().values()) { - BlockVector3 min = region.getMinimumPoint(); - BlockVector3 max = region.getMaximumPoint(); - if (max.getBlockX() - min.getBlockX() > 1024 || max.getBlockZ() - min.getBlockZ() > 1024) { - getLogger(WorldGuardFilter.class).debug("Large or complex region shapes cannot be optimized. Filtering will be slower"); - large = true; - break; - } - add(min.toBlockVector2(), max.toBlockVector2()); + Fawe.get().getQueueHandler().sync(() -> { + WorldGuardFilter.this.manager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(FaweAPI.getWorld(world.getName())); + for (ProtectedRegion region : manager.getRegions().values()) { + BlockVector3 min = region.getMinimumPoint(); + BlockVector3 max = region.getMaximumPoint(); + if (max.getBlockX() - min.getBlockX() > 1024 || max.getBlockZ() - min.getBlockZ() > 1024) { + getLogger(WorldGuardFilter.class).debug("Large or complex region shapes cannot be optimized. Filtering will be slower"); + large = true; + break; } + add(min.toBlockVector2(), max.toBlockVector2()); } }); } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBlockCommandSender.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBlockCommandSender.java index 053edcfad..58d4f12bf 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBlockCommandSender.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBlockCommandSender.java @@ -74,27 +74,6 @@ public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements } } - @Override - public void print(String msg) { - for (String part : msg.split("\n")) { - print(TextComponent.of(part, TextColor.GRAY)); - } - } - - @Override - public void printDebug(String msg) { - for (String part : msg.split("\n")) { - print(TextComponent.of(part, TextColor.GRAY)); - } - } - - @Override - public void printError(String msg) { - for (String part : msg.split("\n")) { - print(TextComponent.of(part, TextColor.RED)); - } - } - @Override public void print(Component component) { TextAdapter.sendComponent(sender, WorldEditText.format(component, getLocale())); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java index a8127e986..3695a9d82 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java @@ -74,27 +74,6 @@ public class BukkitCommandSender extends AbstractNonPlayerActor { } } - @Override - public void print(String msg) { - for (String part : msg.split("\n")) { - sender.sendMessage("\u00A7d" + part); - } - } - - @Override - public void printDebug(String msg) { - for (String part : msg.split("\n")) { - sender.sendMessage("\u00A77" + part); - } - } - - @Override - public void printError(String msg) { - for (String part : msg.split("\n")) { - sender.sendMessage("\u00A7c" + part); - } - } - @Override public void print(Component component) { TextAdapter.sendComponent(sender, WorldEditText.format(component, getLocale())); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 7a6bc550f..a12965769 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -190,6 +190,10 @@ public class BukkitWorld extends AbstractWorld { @Override public boolean regenerate(Region region, EditSession editSession) { + BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); + if (adapter != null) { + return adapter.regenerate(this, region, editSession); + } /* BaseBlock[] history = new BaseBlock[16 * 16 * (getMaxY() + 1)]; @@ -560,7 +564,7 @@ public class BukkitWorld extends AbstractWorld { @Override public IChunkGet get(int chunkX, int chunkZ) { - return new BukkitGetBlocks_1_14(getWorldChecked(), chunkX, chunkZ, Settings.IMP.QUEUE.POOL); + return new BukkitGetBlocks_1_14(getWorldChecked(), chunkX, chunkZ); } @Override diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java index 9006695d2..3fe0a73d5 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java @@ -24,11 +24,13 @@ import com.boydti.fawe.beta.implementation.packet.ChunkPacket; import com.boydti.fawe.bukkit.FaweBukkit; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.world.DataFixer; @@ -232,4 +234,8 @@ public interface BukkitImplAdapter extends IBukkitAdapter { default void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket packet) { throw new UnsupportedOperationException("Cannot send fake chunks"); } + + default boolean regenerate(com.sk89q.worldedit.world.World world, Region region, EditSession editSession) { + return editSession.regenerate(region); + } } \ No newline at end of file diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java index c1d4844bc..efa094056 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java @@ -20,23 +20,35 @@ package com.sk89q.worldedit.bukkit.adapter.impl; import com.bekvon.bukkit.residence.commands.material; +import com.bekvon.bukkit.residence.commands.server; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.implementation.packet.ChunkPacket; +import com.boydti.fawe.beta.implementation.queue.SingleThreadQueueExtent; +import com.boydti.fawe.bukkit.adapter.BukkitQueueHandler; import com.boydti.fawe.bukkit.adapter.mc1_14.BlockMaterial_1_14; import com.boydti.fawe.bukkit.adapter.mc1_14.BukkitAdapter_1_14; +import com.boydti.fawe.bukkit.adapter.mc1_14.BukkitGetBlocks_1_14; import com.boydti.fawe.bukkit.adapter.mc1_14.MapChunkUtil_1_14; import com.boydti.fawe.bukkit.adapter.mc1_14.nbt.LazyCompoundTag_1_14; +import com.google.common.io.Files; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.TileEntityBlock; import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.CachedBukkitAdapter; import com.sk89q.worldedit.bukkit.adapter.IDelegateBukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.impl.Spigot_v1_14_R4; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.LazyBaseEntity; +import com.sk89q.worldedit.math.BlockVector2; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; @@ -50,6 +62,7 @@ import net.minecraft.server.v1_14_R1.Block; import net.minecraft.server.v1_14_R1.BlockPosition; import net.minecraft.server.v1_14_R1.Chunk; import net.minecraft.server.v1_14_R1.ChunkCoordIntPair; +import net.minecraft.server.v1_14_R1.ChunkProviderServer; import net.minecraft.server.v1_14_R1.ChunkSection; import net.minecraft.server.v1_14_R1.Entity; import net.minecraft.server.v1_14_R1.EntityPlayer; @@ -58,6 +71,7 @@ import net.minecraft.server.v1_14_R1.IBlockData; import net.minecraft.server.v1_14_R1.IRegistry; import net.minecraft.server.v1_14_R1.ItemStack; import net.minecraft.server.v1_14_R1.MinecraftKey; +import net.minecraft.server.v1_14_R1.MinecraftServer; import net.minecraft.server.v1_14_R1.NBTBase; import net.minecraft.server.v1_14_R1.NBTTagCompound; import net.minecraft.server.v1_14_R1.NBTTagInt; @@ -65,11 +79,13 @@ import net.minecraft.server.v1_14_R1.PacketPlayOutMapChunk; import net.minecraft.server.v1_14_R1.PlayerChunk; import net.minecraft.server.v1_14_R1.TileEntity; import net.minecraft.server.v1_14_R1.World; +import net.minecraft.server.v1_14_R1.WorldNBTStorage; import net.minecraft.server.v1_14_R1.WorldServer; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_14_R1.CraftChunk; +import org.bukkit.craftbukkit.v1_14_R1.CraftServer; import org.bukkit.craftbukkit.v1_14_R1.CraftWorld; import org.bukkit.craftbukkit.v1_14_R1.block.data.CraftBlockData; import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity; @@ -80,6 +96,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Nullable; +import java.io.File; +import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.OptionalInt; @@ -358,4 +376,53 @@ public final class FAWE_Spigot_v1_14_R4 extends CachedBukkitAdapter implements I } return parent.fromNative(foreign); } + + @Override + public boolean regenerate(com.sk89q.worldedit.world.World world, Region region, EditSession editSession) { + WorldServer originalWorld = ((CraftWorld) world).getHandle(); + ChunkProviderServer provider = originalWorld.getChunkProvider(); + if (!(provider instanceof ChunkProviderServer)) { + return false; + } + + File saveFolder = Files.createTempDir(); + // register this just in case something goes wrong + // normally it should be deleted at the end of this method + saveFolder.deleteOnExit(); + try { + CraftServer server = originalWorld.getServer(); + WorldNBTStorage originalDataManager = originalWorld.getDataManager(); + WorldNBTStorage saveHandler = new WorldNBTStorage(saveFolder, originalDataManager.getDirectory().getName(), server.getServer(), originalDataManager.getDataFixer()); + try (WorldServer freshWorld = new WorldServer(server.getServer(), + server.getServer().executorService, saveHandler, + originalWorld.worldData, + originalWorld.worldProvider.getDimensionManager(), + originalWorld.getMethodProfiler(), + server.getServer().worldLoadListenerFactory.create(11), + ((CraftWorld) world).getEnvironment(), + server.getGenerator(world.getName()))) { + + // Pre-gen all the chunks + // We need to also pull one more chunk in every direction + CuboidRegion expandedPreGen = new CuboidRegion(region.getMinimumPoint().subtract(16, 0, 16), region.getMaximumPoint().add(16, 0, 16)); + for (BlockVector2 chunk : expandedPreGen.getChunks()) { + freshWorld.getChunkAt(chunk.getBlockX(), chunk.getBlockZ()); + } + + // TODO optimize + SingleThreadQueueExtent extent = new SingleThreadQueueExtent(); + extent.init(null, (x, z) -> new BukkitGetBlocks_1_14(freshWorld, x, z), null); + for (BlockVector3 vec : region) { + editSession.setBlock(vec, extent.getFullBlock(vec)); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } catch (MaxChangedBlocksException e) { + throw new RuntimeException(e); + } finally { + saveFolder.delete(); + } + return true; + } } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/command/Rollback.java b/worldedit-core/src/main/java/com/boydti/fawe/command/Rollback.java deleted file mode 100644 index 3723d9cd7..000000000 --- a/worldedit-core/src/main/java/com/boydti/fawe/command/Rollback.java +++ /dev/null @@ -1,184 +0,0 @@ -package com.boydti.fawe.command; - -import com.boydti.fawe.Fawe; -import com.boydti.fawe.FaweAPI; -import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; -import com.boydti.fawe.config.Settings; -import com.boydti.fawe.object.FaweCommand; -import com.boydti.fawe.object.RegionWrapper; -import com.boydti.fawe.object.RunnableVal; -import com.boydti.fawe.object.changeset.DiskStorageHistory; -import com.boydti.fawe.util.MainUtil; -import com.boydti.fawe.util.MathMan; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.entity.Player; -import com.sk89q.worldedit.extension.platform.Actor; -import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.world.World; -import com.sk89q.worldedit.world.block.BlockState; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -public class Rollback extends FaweCommand { - - public Rollback() { - super("fawe.rollback"); - } - - @Override - public boolean execute(Actor actor, String... args) { - if (!(actor.isPlayer() && actor instanceof Player)) { - return false; - } - Player player = (Player) actor; - if (!Settings.IMP.HISTORY.USE_DATABASE) { - player.print(TranslatableComponent.of("fawe.error.setting.disable" , "history.use-database (Import with /frb #import )")); - return false; - } - if (args.length != 3) { - player.print(TranslatableComponent.of("fawe.error.command.syntax" , "/frb u: r: t: