From 8bde93235494c515e944e74ca7b9f36c0626db2a Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 22 Apr 2020 08:10:17 +0100 Subject: [PATCH] Add p2 v4 compat. Anyone that hasn't built FAWE before won't be able to build it again as the v4 repo doesn't exist - it relies on local gradle cache. --- buildSrc/src/main/kotlin/CommonConfig.kt | 1 + .../com/boydti/fawe/bukkit/FaweBukkit.java | 14 +- .../regions/plotsquared/FaweChunkManager.java | 1 - .../plotsquaredv4/FaweChunkManager.java | 118 ++++++++++++ .../plotsquaredv4/FaweLocalBlockQueue.java | 130 +++++++++++++ .../plotsquaredv4/FaweSchematicHandler.java | 139 ++++++++++++++ .../regions/plotsquaredv4/FaweTrim.java | 56 ++++++ .../plotsquaredv4/PlotRegionFilter.java | 28 +++ .../regions/plotsquaredv4/PlotSetBiome.java | 93 ++++++++++ .../plotsquaredv4/PlotSquaredFeature.java | 174 ++++++++++++++++++ worldedit-core/build.gradle.kts | 4 + 11 files changed, 754 insertions(+), 4 deletions(-) create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweChunkManager.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweLocalBlockQueue.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweSchematicHandler.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweTrim.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/PlotRegionFilter.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/PlotSetBiome.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/PlotSquaredFeature.java diff --git a/buildSrc/src/main/kotlin/CommonConfig.kt b/buildSrc/src/main/kotlin/CommonConfig.kt index 8751d3f42..e2d7a1ba1 100644 --- a/buildSrc/src/main/kotlin/CommonConfig.kt +++ b/buildSrc/src/main/kotlin/CommonConfig.kt @@ -9,6 +9,7 @@ fun Project.applyCommonConfiguration() { mavenCentral() mavenLocal() maven { url = uri("https://plotsquared.com/mvn/") } + maven { url = uri("http://ci.athion.net/job/PlotSquared-breaking/ws/mvn/") } maven { url = uri("https://maven.sk89q.com/repo/") } maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots/") } maven { url = uri("https://ci.athion.net/plugin/repository/tools/") } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java index df2cb23ae..d3100c23d 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java @@ -305,8 +305,16 @@ public class FaweBukkit implements IFawe, Listener { } private void setupPlotSquared() { - if(this.plugin.getServer().getPluginManager().getPlugin("PlotSquared") == null) return; - WEManager.IMP.managers.add(new com.boydti.fawe.bukkit.regions.plotsquared.PlotSquaredFeature()); - log.debug("Plugin 'PlotSquared' found. Using it now."); + Plugin plotSquared = this.plugin.getServer().getPluginManager().getPlugin("PlotSquared"); + if (plotSquared == null) + return; + if (plotSquared.getClass().getPackage().toString().contains("intellectualsites")) { + WEManager.IMP.managers + .add(new com.boydti.fawe.bukkit.regions.plotsquaredv4.PlotSquaredFeature()); + } else { + WEManager.IMP.managers + .add(new com.boydti.fawe.bukkit.regions.plotsquared.PlotSquaredFeature()); + } + log.info("Plugin 'PlotSquared' found. Using it now."); } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquared/FaweChunkManager.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquared/FaweChunkManager.java index b8381ea90..a33de77c1 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquared/FaweChunkManager.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquared/FaweChunkManager.java @@ -18,7 +18,6 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.World; import java.util.concurrent.CompletableFuture; -import org.bukkit.Bukkit; public class FaweChunkManager extends ChunkManager { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweChunkManager.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweChunkManager.java new file mode 100644 index 000000000..b4b11f439 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweChunkManager.java @@ -0,0 +1,118 @@ +package com.boydti.fawe.bukkit.regions.plotsquaredv4; + +import static org.bukkit.Bukkit.getWorld; + +import com.boydti.fawe.util.EditSessionBuilder; +import com.boydti.fawe.util.TaskManager; +import com.github.intellectualsites.plotsquared.plot.object.Location; +import com.github.intellectualsites.plotsquared.plot.object.Plot; +import com.github.intellectualsites.plotsquared.plot.util.ChunkManager; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.function.operation.ForwardExtentCopy; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.math.BlockVector2; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.world.World; +import java.util.concurrent.CompletableFuture; + +public class FaweChunkManager extends ChunkManager { + + private ChunkManager parent; + + public FaweChunkManager(ChunkManager parent) { + this.parent = parent; + } + + @Override + public int[] countEntities(Plot plot) { + return parent.countEntities(plot); + } + + @Override + public CompletableFuture loadChunk(String world, BlockVector2 loc, boolean force) { + return parent.loadChunk(world, loc, force); + } + + @Override + public void unloadChunk(String world, BlockVector2 loc, boolean save) { + parent.unloadChunk(world, loc, save); + } + + @Override + public void clearAllEntities(Location pos1, Location pos2) { + parent.clearAllEntities(pos1, pos2); + } + + @Override + public void swap(final Location pos1, final Location pos2, final Location pos3, final Location pos4, final Runnable whenDone) { + TaskManager.IMP.async(() -> { + synchronized (FaweChunkManager.class) { + //todo because of the following code this should proably be in the Bukkit module + World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorld())); + World pos3World = BukkitAdapter.adapt(getWorld(pos3.getWorld())); + WorldEdit.getInstance().getEditSessionFactory().getEditSession( + pos1World,-1); + EditSession sessionA = new EditSessionBuilder(pos1World).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build(); + EditSession sessionB = new EditSessionBuilder(pos3World).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build(); + CuboidRegion regionA = new CuboidRegion(BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()), BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ())); + CuboidRegion regionB = new CuboidRegion(BlockVector3.at(pos3.getX(), pos3.getY(), pos3.getZ()), BlockVector3.at(pos4.getX(), pos4.getY(), pos4.getZ())); + ForwardExtentCopy copyA = new ForwardExtentCopy(sessionA, regionA, sessionB, regionB.getMinimumPoint()); + ForwardExtentCopy copyB = new ForwardExtentCopy(sessionB, regionB, sessionA, regionA.getMinimumPoint()); + try { + Operations.completeLegacy(copyA); + Operations.completeLegacy(copyB); + sessionA.flushQueue(); + sessionB.flushQueue(); + } catch (MaxChangedBlocksException e) { + e.printStackTrace(); + } + TaskManager.IMP.task(whenDone); + } + }); + } + + @Override + public boolean copyRegion(final Location pos1, final Location pos2, final Location pos3, final Runnable whenDone) { + TaskManager.IMP.async(() -> { + synchronized (FaweChunkManager.class) { + World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorld())); + World pos3World = BukkitAdapter.adapt(getWorld(pos3.getWorld())); + EditSession from = new EditSessionBuilder(pos1World).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build(); + EditSession to = new EditSessionBuilder(pos3World).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build(); + CuboidRegion region = new CuboidRegion(BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()), BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ())); + ForwardExtentCopy copy = new ForwardExtentCopy(from, region, to, BlockVector3.at(pos3.getX(), pos3.getY(), pos3.getZ())); + try { + Operations.completeLegacy(copy); + to.flushQueue(); + } catch (MaxChangedBlocksException e) { + e.printStackTrace(); + } + } + TaskManager.IMP.task(whenDone); + }); + return true; + } + + @Override + public boolean regenerateRegion(final Location pos1, final Location pos2, boolean ignore, final Runnable whenDone) { + TaskManager.IMP.async(() -> { + synchronized (FaweChunkManager.class) { + World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorld())); + try (EditSession editSession = new EditSessionBuilder(pos1World).checkMemory(false) + .fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build()) { + CuboidRegion region = new CuboidRegion( + BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()), + BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ())); + editSession.regenerate(region); + editSession.flushQueue(); + } + TaskManager.IMP.task(whenDone); + } + }); + return true; + } +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweLocalBlockQueue.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweLocalBlockQueue.java new file mode 100644 index 000000000..3a1edb0b0 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweLocalBlockQueue.java @@ -0,0 +1,130 @@ +package com.boydti.fawe.bukkit.regions.plotsquaredv4; + +import com.boydti.fawe.Fawe; +import com.boydti.fawe.FaweAPI; +import com.boydti.fawe.FaweCache; +import com.boydti.fawe.beta.IQueueChunk; +import com.boydti.fawe.beta.IQueueExtent; +import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.math.MutableBlockVector3; +import com.sk89q.worldedit.world.World; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockState; + +// TODO FIXME +public class FaweLocalBlockQueue extends LocalBlockQueue { + + public final IQueueExtent instance; + private final World world; + private BlockVector3 mutable = new MutableBlockVector3(); + + public FaweLocalBlockQueue(String worldName) { + super(worldName); + this.world = FaweAPI.getWorld(worldName); + instance = Fawe.get().getQueueHandler().getQueue(world); + Fawe.get().getQueueHandler().unCache(); + } + + @Override + public boolean next() { + if (!instance.isEmpty()) { + instance.flush(); + } + return false; + } + + @Override + public void startSet(boolean parallel) { + Fawe.get().getQueueHandler().startSet(parallel); + } + + @Override + public void endSet(boolean parallel) { + Fawe.get().getQueueHandler().endSet(parallel); + } + + @Override + public int size() { + return instance.isEmpty() ? 0 : 1; + } + + @Override + public void optimize() { + } + + @Override + public void setModified(long l) { + } + + @Override + public long getModified() { + return instance.size(); + } + + @Override + public boolean setBlock(final int x, final int y, final int z, final BlockState id) { + return instance.setBlock(x, y, z, id); + } + + @Override + public boolean setBlock(int x, int y, int z, Pattern pattern) { + mutable.setComponents(x, y, z); + return pattern.apply(instance, mutable, mutable); + } + + @Override + public boolean setBlock(final int x, final int y, final int z, final BaseBlock id) { + return instance.setBlock(x, y, z, id); + } + + @Override + public BlockState getBlock(int x, int y, int z) { + return instance.getBlock(x, y, z); + } + + @Override + public boolean setBiome(int x, int z, BiomeType biomeType) { + return instance.setBiome(x, 0, z, biomeType); + } + + @Override + public String getWorld() { + return world.getId(); + } + + @Override + public void flush() { + instance.flush(); + } + + @Override + public boolean enqueue() { + boolean val = super.enqueue(); + instance.enableQueue(); + return val; + } + + @Override + public void refreshChunk(int x, int z) { + world.refreshChunk(x, z); + } + + @Override + public void fixChunkLighting(int x, int z) { + } + + @Override + public void regenChunk(int x, int z) { + instance.regenerateChunk(x, z, null, null); + } + + @Override + public boolean setTile(int x, int y, int z, CompoundTag tag) { + instance.setTile(x, y, z, (com.sk89q.jnbt.CompoundTag) FaweCache.IMP.asTag(tag)); + return true; + } +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweSchematicHandler.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweSchematicHandler.java new file mode 100644 index 000000000..40d0668f1 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweSchematicHandler.java @@ -0,0 +1,139 @@ +package com.boydti.fawe.bukkit.regions.plotsquaredv4; + +import static org.bukkit.Bukkit.getWorld; + +import com.boydti.fawe.FaweAPI; +import com.boydti.fawe.FaweCache; +import com.boydti.fawe.object.clipboard.ReadOnlyClipboard; +import com.boydti.fawe.object.io.PGZIPOutputStream; +import com.boydti.fawe.util.EditSessionBuilder; +import com.boydti.fawe.util.IOUtil; +import com.boydti.fawe.util.TaskManager; +import com.github.intellectualsites.plotsquared.plot.PlotSquared; +import com.github.intellectualsites.plotsquared.plot.object.Location; +import com.github.intellectualsites.plotsquared.plot.object.RunnableVal; +import com.github.intellectualsites.plotsquared.plot.util.MainUtil; +import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler; +import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.CompressedCompoundTag; +import com.sk89q.jnbt.CompressedSchematicTag; +import com.sk89q.jnbt.NBTOutputStream; +import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat; +import com.sk89q.worldedit.extent.clipboard.io.FastSchematicWriter; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.world.World; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import net.jpountz.lz4.LZ4BlockInputStream; + +public class FaweSchematicHandler extends SchematicHandler { + @Override + public boolean restoreTile(LocalBlockQueue queue, CompoundTag compoundTag, int x, int y, int z) { + if (queue instanceof FaweLocalBlockQueue) { + queue.setTile(x, y, z, compoundTag); + return true; + } + return false; + } + + @Override + public void getCompoundTag(final String world, final Set regions, final RunnableVal whenDone) { + TaskManager.IMP.async(() -> { + Location[] corners = MainUtil.getCorners(world, regions); + Location pos1 = corners[0]; + Location pos2 = corners[1]; + World adaptedWorld = BukkitAdapter.adapt(getWorld(world)); + final CuboidRegion region = new CuboidRegion(BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()), BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ())); + final EditSession editSession = new EditSessionBuilder(adaptedWorld).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build(); + + ReadOnlyClipboard clipboard = ReadOnlyClipboard.of(editSession, region, false, true); + + Clipboard holder = new BlockArrayClipboard(region, clipboard); + CompressedSchematicTag tag = new CompressedSchematicTag(holder); + whenDone.run(tag); + }); + } + + @Override + public boolean save(CompoundTag tag, String path) { + if (tag == null) { + PlotSquared.debug("&cCannot save empty tag"); + return false; + } + try { + File tmp = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), path); + tmp.getParentFile().mkdirs(); + if (tag instanceof CompressedCompoundTag) { + CompressedCompoundTag cTag = (CompressedCompoundTag) tag; + if (cTag instanceof CompressedSchematicTag) { + Clipboard clipboard = (Clipboard) cTag.getSource(); + try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream(new BufferedOutputStream(new PGZIPOutputStream(stream)))) { + new FastSchematicWriter(output).write(clipboard); + } + } else { + try (OutputStream stream = new FileOutputStream(tmp); BufferedOutputStream output = new BufferedOutputStream(new PGZIPOutputStream(stream))) { + LZ4BlockInputStream is = cTag.adapt(cTag.getSource()); + IOUtil.copy(is, stream); + } + } + } else { + try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream(new PGZIPOutputStream(stream))) { + Map map = tag.getValue(); + output.writeNamedTag("Schematic", map.getOrDefault("Schematic", tag)); + } + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + return true; + } + + @Override + public void upload(final CompoundTag tag, final UUID uuid, final String file, final RunnableVal whenDone) { + if (tag == null) { + PlotSquared.debug("&cCannot save empty tag"); + com.github.intellectualsites.plotsquared.plot.util.TaskManager.runTask(whenDone); + return; + } + CompoundTag weTag = (CompoundTag) FaweCache.IMP.asTag(tag); + if (weTag instanceof CompressedSchematicTag) { + Clipboard clipboard = ((CompressedSchematicTag) weTag).getSource(); + URL url = FaweAPI.upload(clipboard, BuiltInClipboardFormat.SPONGE_SCHEMATIC); + whenDone.run(url); + return; + } + MainUtil.upload(uuid, file, "schem", new RunnableVal() { + @Override + public void run(OutputStream output) { + try { + try (PGZIPOutputStream gzip = new PGZIPOutputStream(output)) { + try (NBTOutputStream nos = new NBTOutputStream(gzip)) { + Map map = weTag.getValue(); + nos.writeNamedTag("Schematic", map.getOrDefault("Schematic", weTag)); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + }, whenDone); + } +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweTrim.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweTrim.java new file mode 100644 index 000000000..6a5ba286b --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweTrim.java @@ -0,0 +1,56 @@ +package com.boydti.fawe.bukkit.regions.plotsquaredv4; + +import com.boydti.fawe.util.TaskManager; +import com.github.intellectualsites.plotsquared.commands.CommandDeclaration; +import com.github.intellectualsites.plotsquared.plot.commands.CommandCategory; +import com.github.intellectualsites.plotsquared.plot.commands.RequiredType; +import com.github.intellectualsites.plotsquared.plot.commands.SubCommand; +import com.github.intellectualsites.plotsquared.plot.config.Captions; +import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; +import com.github.intellectualsites.plotsquared.plot.util.WorldUtil; + +@CommandDeclaration( + command = "trimchunks", + permission = "plots.admin", + description = "Delete unmodified portions of your plotworld", + requiredType = RequiredType.PLAYER, + category = CommandCategory.ADMINISTRATION) +public class FaweTrim extends SubCommand { + + private boolean ran = false; + + @Override + public boolean onCommand(final PlotPlayer plotPlayer, final String[] strings) { + if (ran) { + plotPlayer.sendMessage("Already running!"); + return false; + } + if (strings.length != 2) { + plotPlayer.sendMessage("First make a backup of your world called then stand in the middle of an empty plot"); + plotPlayer.sendMessage("use /plot trimall "); + return false; + } + if (!WorldUtil.IMP.isWorld(strings[0])) { + Captions.NOT_VALID_PLOT_WORLD.send(plotPlayer, strings[0]); + return false; + } + ran = true; + TaskManager.IMP.async(new Runnable() { + @Override + public void run() { + try { + // TODO NOT IMPLEMENTED +// PlotTrim trim = new PlotTrim(plotPlayer, plotPlayer.getPlotAreaAbs(), strings[0], Boolean.parseBoolean(strings[1])); +// Location loc = plotPlayer.getLocation(); +// trim.setChunk(loc.getX() >> 4, loc.getZ() >> 4); +// trim.run(); +// plotPlayer.sendMessage("Done!"); + } catch (Throwable e) { + e.printStackTrace(); + } + ran = false; + } + }); + return true; + } +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/PlotRegionFilter.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/PlotRegionFilter.java new file mode 100644 index 000000000..bf1408415 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/PlotRegionFilter.java @@ -0,0 +1,28 @@ +package com.boydti.fawe.bukkit.regions.plotsquaredv4; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.boydti.fawe.regions.general.CuboidRegionFilter; +import com.github.intellectualsites.plotsquared.plot.object.Location; +import com.github.intellectualsites.plotsquared.plot.object.Plot; +import com.github.intellectualsites.plotsquared.plot.object.PlotArea; +import com.sk89q.worldedit.math.BlockVector2; +import java.util.ArrayList; + +public class PlotRegionFilter extends CuboidRegionFilter { + private final PlotArea area; + + public PlotRegionFilter(PlotArea area) { + checkNotNull(area); + this.area = area; + } + @Override + public void calculateRegions() { + ArrayList plots = new ArrayList<>(area.getPlots()); + for (Plot plot : plots) { + Location bottom = plot.getCorners()[0]; + Location top = plot.getCorners()[1]; + add(BlockVector2.at(bottom.getX(), bottom.getZ()), BlockVector2.at(top.getX(), top.getZ())); + } + } +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/PlotSetBiome.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/PlotSetBiome.java new file mode 100644 index 000000000..c822700fe --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/PlotSetBiome.java @@ -0,0 +1,93 @@ +package com.boydti.fawe.bukkit.regions.plotsquaredv4; + +import com.boydti.fawe.util.EditSessionBuilder; +import com.boydti.fawe.util.TaskManager; +import com.github.intellectualsites.plotsquared.commands.Command; +import com.github.intellectualsites.plotsquared.commands.CommandDeclaration; +import com.github.intellectualsites.plotsquared.plot.commands.CommandCategory; +import com.github.intellectualsites.plotsquared.plot.commands.MainCommand; +import com.github.intellectualsites.plotsquared.plot.commands.RequiredType; +import com.github.intellectualsites.plotsquared.plot.config.Captions; +import com.github.intellectualsites.plotsquared.plot.object.Plot; +import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; +import com.github.intellectualsites.plotsquared.plot.object.RunnableVal2; +import com.github.intellectualsites.plotsquared.plot.object.RunnableVal3; +import com.github.intellectualsites.plotsquared.plot.util.MainUtil; +import com.github.intellectualsites.plotsquared.plot.util.Permissions; +import com.github.intellectualsites.plotsquared.plot.util.StringMan; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.extension.platform.Capability; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.biome.BiomeTypes; +import com.sk89q.worldedit.world.biome.Biomes; +import com.sk89q.worldedit.world.registry.BiomeRegistry; +import java.util.Collection; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ThreadLocalRandom; +import org.bukkit.Bukkit; + +@CommandDeclaration( + command = "generatebiome", + permission = "plots.generatebiome", + category = CommandCategory.APPEARANCE, + requiredType = RequiredType.NONE, + description = "Generate a biome in your plot", + aliases = {"bg", "gb"}, + usage = "/plots generatebiome " +) +public class PlotSetBiome extends Command { + public PlotSetBiome() { + super(MainCommand.getInstance(), true); + } + + @Override + public CompletableFuture execute(final PlotPlayer player, String[] args, RunnableVal3 confirm, RunnableVal2 whenDone) throws CommandException { + final Plot plot = check(player.getCurrentPlot(), Captions.NOT_IN_PLOT); + checkTrue(plot.isOwner(player.getUUID()) || Permissions + .hasPermission(player, "plots.admin.command.generatebiome"), Captions.NO_PLOT_PERMS); + if (plot.getRunning() != 0) { + Captions.WAIT_FOR_TIMER.send(player); + return null; + } + checkTrue(args.length == 1, Captions.COMMAND_SYNTAX, getUsage()); + final Set regions = plot.getRegions(); + BiomeRegistry biomeRegistry = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry(); + Collection knownBiomes = BiomeTypes.values(); + final BiomeType biome = Biomes.findBiomeByName(knownBiomes, args[0], biomeRegistry); + if (biome == null) { + String biomes = StringMan + .join(BiomeType.REGISTRY.values(), Captions.BLOCK_LIST_SEPARATOR.getTranslated()); + Captions.NEED_BIOME.send(player); + MainUtil.sendMessage(player, Captions.SUBCOMMAND_SET_OPTIONS_HEADER.toString() + biomes); + return CompletableFuture.completedFuture(false); + } + confirm.run(this, () -> { + if (plot.getRunning() != 0) { + Captions.WAIT_FOR_TIMER.send(player); + return; + } + plot.addRunning(); + TaskManager.IMP.async(() -> { + EditSession session = new EditSessionBuilder(BukkitAdapter.adapt(Bukkit.getWorld(plot.getArea().worldname))) + .autoQueue(false) + .checkMemory(false) + .allowedRegionsEverywhere() + .player(BukkitAdapter.adapt(Bukkit.getPlayer(player.getUUID()))) + .limitUnlimited() + .build(); + long seed = ThreadLocalRandom.current().nextLong(); + for (CuboidRegion region : regions) { + session.regenerate(region, biome, seed); + } + session.flushQueue(); + plot.removeRunning(); + }); + }, null); + + return CompletableFuture.completedFuture(true); + } +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/PlotSquaredFeature.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/PlotSquaredFeature.java new file mode 100644 index 000000000..5ba0d0dad --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/PlotSquaredFeature.java @@ -0,0 +1,174 @@ +package com.boydti.fawe.bukkit.regions.plotsquaredv4; + +import com.boydti.fawe.FaweAPI; +import com.boydti.fawe.object.RegionWrapper; +import com.boydti.fawe.regions.FaweMask; +import com.boydti.fawe.regions.FaweMaskManager; +import com.boydti.fawe.regions.general.RegionFilter; +import com.github.intellectualsites.plotsquared.plot.PlotSquared; +import com.github.intellectualsites.plotsquared.plot.commands.MainCommand; +import com.github.intellectualsites.plotsquared.plot.config.Settings; +import com.github.intellectualsites.plotsquared.plot.database.DBFunc; +import com.github.intellectualsites.plotsquared.plot.flag.Flags; +import com.github.intellectualsites.plotsquared.plot.generator.HybridPlotManager; +import com.github.intellectualsites.plotsquared.plot.listener.WEManager; +import com.github.intellectualsites.plotsquared.plot.object.Plot; +import com.github.intellectualsites.plotsquared.plot.object.PlotArea; +import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; +import com.github.intellectualsites.plotsquared.plot.util.ChunkManager; +import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler; +import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler; +import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue; +import com.github.intellectualsites.plotsquared.plot.util.block.QueueProvider; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.regions.RegionIntersection; +import com.sk89q.worldedit.world.World; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PlotSquaredFeature extends FaweMaskManager { + + private static final Logger log = LoggerFactory.getLogger(PlotSquaredFeature.class); + + public PlotSquaredFeature() { + super("PlotSquared"); + log.debug("Optimizing PlotSquared"); + if (com.boydti.fawe.config.Settings.IMP.PLOTSQUARED_HOOK) { + Settings.Enabled_Components.WORLDEDIT_RESTRICTIONS = false; + try { + setupBlockQueue(); + setupSchematicHandler(); + setupChunkManager(); + } catch (Throwable ignored) { + log.debug("Please update PlotSquared: http://ci.athion.net/job/PlotSquared/"); + } + if (Settings.PLATFORM.toLowerCase().startsWith("bukkit")) { + new FaweTrim(); + } + if (MainCommand.getInstance().getCommand("generatebiome") == null) { + new PlotSetBiome(); + } + } +// TODO: revisit this later on +/* + try { + if (Settings.Enabled_Components.WORLDS) { + new ReplaceAll(); + } + } catch (Throwable e) { + log.debug("You need to update PlotSquared to access the CFI and REPLACEALL commands"); + } +*/ + } + + public static String getName(UUID uuid) { + return UUIDHandler.getName(uuid); + } + + private void setupBlockQueue() throws RuntimeException { + // If it's going to fail, throw an error now rather than later + //QueueProvider provider = QueueProvider.of(FaweLocalBlockQueue.class, null); + //GlobalBlockQueue.IMP.setProvider(provider); + HybridPlotManager.REGENERATIVE_CLEAR = false; + //log.debug(" - QueueProvider: " + FaweLocalBlockQueue.class); + log.debug(" - HybridPlotManager.REGENERATIVE_CLEAR: " + HybridPlotManager.REGENERATIVE_CLEAR); + } + + private void setupChunkManager() throws RuntimeException { + ChunkManager.manager = new FaweChunkManager(ChunkManager.manager); + log.debug(" - ChunkManager: " + ChunkManager.manager); + } + + private void setupSchematicHandler() throws RuntimeException { + SchematicHandler.manager = new FaweSchematicHandler(); + log.debug(" - SchematicHandler: " + SchematicHandler.manager); + } + + public boolean isAllowed(Player player, Plot plot, MaskType type) { + if (plot == null) { + return false; + } + UUID uid = player.getUniqueId(); + return !Flags.NO_WORLDEDIT.isTrue(plot) && (plot.isOwner(uid) + || type == MaskType.MEMBER && (plot.getTrusted().contains(uid) || plot.getTrusted() + .contains(DBFunc.EVERYONE) + || (plot.getMembers().contains(uid) || plot.getMembers().contains(DBFunc.EVERYONE)) + && player.hasPermission("fawe.plotsquared.member")) || player + .hasPermission("fawe.plotsquared.admin")); + } + + @Override + public FaweMask getMask(Player player, MaskType type) { + final PlotPlayer pp = PlotPlayer.wrap(player.getUniqueId()); + if (pp == null) { + return null; + } + final Set regions; + Plot plot = pp.getCurrentPlot(); + if (isAllowed(player, plot, type)) { + regions = plot.getRegions(); + } else { + plot = null; + regions = WEManager.getMask(pp); + if (regions.size() == 1) { + CuboidRegion region = regions.iterator().next(); + if (region.getMinimumPoint().getX() == Integer.MIN_VALUE && region.getMaximumPoint().getX() == Integer.MAX_VALUE) { + regions.clear(); + } + } + } + if (regions.isEmpty()) { + return null; + } + PlotArea area = pp.getApplicablePlotArea(); + int min = area != null ? area.MIN_BUILD_HEIGHT : 0; + int max = area != null ? Math.min(255, area.MAX_BUILD_HEIGHT) : 255; + final HashSet faweRegions = new HashSet<>(); + for (CuboidRegion current : regions) { + faweRegions.add(new RegionWrapper(current.getMinimumX(), current.getMaximumX(), min, max, current.getMinimumZ(), current.getMaximumZ())); + } + final CuboidRegion region = regions.iterator().next(); + final BlockVector3 pos1 = BlockVector3.at(region.getMinimumX(), min, region.getMinimumZ()); + final BlockVector3 pos2 = BlockVector3.at(region.getMaximumX(), max, region.getMaximumZ()); + final Plot finalPlot = plot; + if (Settings.Done.RESTRICT_BUILDING && Flags.DONE.isSet(finalPlot) || regions.isEmpty()) { + return null; + } + + Region maskedRegion; + if (regions.size() == 1) { + maskedRegion = new CuboidRegion(pos1, pos2); + } else { + World world = FaweAPI.getWorld(area.worldname); + List weRegions = regions.stream() + .map(r -> new CuboidRegion(world, BlockVector3.at(r.getMinimumX(), r.getMinimumY(), r.getMinimumZ()), BlockVector3.at(r.getMaximumX(), r.getMaximumY(), r.getMaximumZ()))) + .collect(Collectors.toList()); + maskedRegion = new RegionIntersection(world, weRegions); + } + + return new FaweMask(maskedRegion) { + @Override + public boolean isValid(Player player, MaskType type) { + if (Settings.Done.RESTRICT_BUILDING && Flags.DONE.isSet(finalPlot)) { + return false; + } + return isAllowed(player, finalPlot, type); + } + }; + } + + @Override + public RegionFilter getFilter(String world) { + PlotArea area = PlotSquared.get().getPlotArea(world, null); + if (area != null) return new PlotRegionFilter(area); + return null; + } +} diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index 3984aa78e..8021524e4 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -15,6 +15,7 @@ plugins { repositories { maven { url = uri("https://plotsquared.com/mvn") } + maven { url = uri("http://ci.athion.net/job/PlotSquared-breaking/ws/mvn/") } mavenCentral() } @@ -55,6 +56,9 @@ dependencies { "compile"("co.aikar:fastutil-lite:1.0") "compile"("com.github.luben:zstd-jni:1.4.3-1") "compileOnly"("net.fabiozumbi12:redprotect:1.9.6") + "compile"("com.github.intellectualsites.plotsquared:PlotSquared-API:latest") { + isTransitive = false + } "compile"("com.plotsquared:PlotSquared:5.1") { isTransitive = false }