From 7f01ac7790ad14febac8b7bed4bb96c29553761b Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Wed, 5 Jul 2017 18:53:05 +1000 Subject: [PATCH] Various minor Fix nukkit compile Fix setBlocks with BlockPattern MCAQueue filterCopy API (performs operations on a copy of the world) Add //anvil trimallplots --- build.gradle | 6 +- bukkit/build.gradle | 1 + .../fawe/bukkit/v1_12/FaweChunkPacket.java | 85 +++++++++ .../boydti/fawe/command/AnvilCommands.java | 82 ++++++-- .../java/com/boydti/fawe/config/Settings.java | 2 +- .../com/boydti/fawe/jnbt/anvil/MCAFile.java | 30 ++- .../com/boydti/fawe/jnbt/anvil/MCAFilter.java | 6 + .../com/boydti/fawe/jnbt/anvil/MCAQueue.java | 150 ++++++++++++++- .../jnbt/anvil/filters/DeleteOldFilter.java | 28 +++ .../filters/DeleteUninhabitedFilter.java | 117 +++++++----- .../jnbt/anvil/filters/PlotTrimFilter.java | 111 +++++++---- .../boydti/fawe/object/FaweOutputStream.java | 17 ++ .../fawe/object/collection/LongHashSet.java | 178 ++++++++++++++++++ .../java/com/sk89q/worldedit/EditSession.java | 2 +- nukkit/build.gradle | 2 +- .../fawe/nukkit/optimization/FaweNukkit.java | 12 +- 16 files changed, 707 insertions(+), 122 deletions(-) create mode 100644 bukkit/src/main/java/com/boydti/fawe/bukkit/v1_12/FaweChunkPacket.java create mode 100644 core/src/main/java/com/boydti/fawe/jnbt/anvil/filters/DeleteOldFilter.java create mode 100644 core/src/main/java/com/boydti/fawe/object/collection/LongHashSet.java diff --git a/build.gradle b/build.gradle index d5daa5e4..b9e44add 100644 --- a/build.gradle +++ b/build.gradle @@ -69,6 +69,7 @@ if ( project.hasProperty("lzNoVersion") ) { // gradle build -PlzNoVersion description = """FastAsyncWorldEdit""" subprojects { + apply plugin: 'java' apply plugin: 'maven' apply plugin: 'eclipse' @@ -79,10 +80,11 @@ subprojects { repositories { mavenCentral() + maven {url "http://repo.dmulloy2.net/content/groups/public/"} maven {url "https://repo.destroystokyo.com/repository/maven-public//"} maven { url = "https://mvnrepository.com/artifact/"} maven {url "http://ci.emc.gs/nexus/content/groups/aikar/" } - maven {url "http://ci.mengcraft.com:8080/plugin/repository/everything/"} + maven {url "http://ci.mengcraft.com:8080/plugin/repository/everything"} maven {url "http://ci.athion.net/job/PlotSquared/ws/mvn/"} maven {url "http://empcraft.com/maven2"} maven {url "https://hub.spigotmc.org/nexus/content/groups/public/"} @@ -90,7 +92,7 @@ subprojects { maven {url "http://nexus.hc.to/content/repositories/pub_releases"} maven {url "http://repo.maven.apache.org/maven2"} maven {url "http://ci.frostcast.net/plugin/repository/everything"} - maven {url "http://maven.sk89q.com/artifactory/repo/"} + maven {url "http://maven.sk89q.com/artifactory/repo"} maven {url "http://repo.spongepowered.org/maven"} } } diff --git a/bukkit/build.gradle b/bukkit/build.gradle index 2c38d2ee..051da304 100644 --- a/bukkit/build.gradle +++ b/bukkit/build.gradle @@ -25,6 +25,7 @@ dependencies { compile 'org.bukkit.craftbukkit.v1_9R2:craftbukkitv1_9R2:1.9.4' compile 'org.bukkit.craftbukkit:Craftbukkit:1.7.10' compile 'org.bukkit.craftbukkit:CraftBukkit:1.8.8' + compile 'com.comphenix.protocol:ProtocolLib-API:4.3.1-SNAPSHOT' } processResources { diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_12/FaweChunkPacket.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_12/FaweChunkPacket.java new file mode 100644 index 00000000..9e1f46d4 --- /dev/null +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_12/FaweChunkPacket.java @@ -0,0 +1,85 @@ +package com.boydti.fawe.bukkit.v1_12; + +import com.boydti.fawe.FaweCache; +import com.boydti.fawe.jnbt.anvil.MCAChunk; +import com.boydti.fawe.object.FaweOutputStream; +import com.boydti.fawe.object.io.FastByteArrayOutputStream; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.StructureModifier; +import com.comphenix.protocol.wrappers.nbt.NbtBase; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import net.minecraft.server.v1_12_R1.Block; +import net.minecraft.server.v1_12_R1.DataBits; +import net.minecraft.server.v1_12_R1.MathHelper; + +public class FaweChunkPacket { + + private final MCAChunk chunk; + private final boolean full; + private final boolean biomes; + private final boolean sky; + + public FaweChunkPacket(MCAChunk fc, boolean replaceAllSections, boolean sendBiomeData, boolean hasSky) { + this.chunk = fc; + this.full = replaceAllSections; + this.biomes = sendBiomeData; + this.sky = hasSky; + } + + public void write(PacketContainer packet) throws IOException { + try { + StructureModifier ints = packet.getIntegers(); + StructureModifier byteArray = packet.getByteArrays(); + StructureModifier bools = packet.getBooleans(); + ints.write(0, this.chunk.getX()); + ints.write(1, this.chunk.getZ()); + + bools.write(0, this.full); + ints.write(2, this.chunk.getBitMask()); // writeVarInt + + FastByteArrayOutputStream fbaos = new FastByteArrayOutputStream(); + FaweOutputStream buffer = new FaweOutputStream(fbaos); + byte[][] ids = chunk.ids; + + for (int layer = 0; layer < ids.length; layer++) { + byte[] layerIds = ids[layer]; + if (layerIds == null) { + continue; + } + byte[] layerData = chunk.data[layer]; + int num = MathHelper.d(Block.REGISTRY_ID.a()); + buffer.write(num); // num blocks, anything > 8 - doesn't need to be accurate + buffer.writeVarInt(0); // varint 0 - data palette global + DataBits bits = new DataBits(num, 4096); + for (int i = 0; i < 4096; i++) { + int id = layerIds[i]; + if (id != 0) { + int data = FaweCache.hasData(id) ? chunk.getNibble(i, layerData) : 0; + int combined = FaweCache.getCombined(id, data); + bits.a(i, combined); + } + } + buffer.write(bits.a()); + + buffer.write(chunk.blockLight[layer]); + if (sky) { + buffer.write(chunk.skyLight[layer]); + } + } + + if (this.biomes && chunk.biomes != null) { + buffer.write(chunk.biomes); + } + + byteArray.write(0, fbaos.toByteArray()); + + // TODO - empty + StructureModifier>> list = packet.getListNbtModifier(); + list.write(0, new ArrayList<>()); + } catch (Throwable e) { + e.printStackTrace(); + } + } +} diff --git a/core/src/main/java/com/boydti/fawe/command/AnvilCommands.java b/core/src/main/java/com/boydti/fawe/command/AnvilCommands.java index cb11b7c5..1d562dac 100644 --- a/core/src/main/java/com/boydti/fawe/command/AnvilCommands.java +++ b/core/src/main/java/com/boydti/fawe/command/AnvilCommands.java @@ -11,8 +11,10 @@ import com.boydti.fawe.jnbt.anvil.MCAFilterCounter; import com.boydti.fawe.jnbt.anvil.MCAQueue; import com.boydti.fawe.jnbt.anvil.filters.CountFilter; import com.boydti.fawe.jnbt.anvil.filters.CountIdFilter; +import com.boydti.fawe.jnbt.anvil.filters.DeleteOldFilter; import com.boydti.fawe.jnbt.anvil.filters.DeleteUninhabitedFilter; import com.boydti.fawe.jnbt.anvil.filters.MappedReplacePatternFilter; +import com.boydti.fawe.jnbt.anvil.filters.PlotTrimFilter; import com.boydti.fawe.jnbt.anvil.filters.RemoveLayerFilter; import com.boydti.fawe.jnbt.anvil.filters.ReplacePatternFilter; import com.boydti.fawe.jnbt.anvil.filters.ReplaceSimpleFilter; @@ -21,6 +23,7 @@ import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.RegionWrapper; import com.boydti.fawe.object.RunnableVal4; import com.boydti.fawe.object.mask.FaweBlockMatcher; +import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.SetQueue; import com.boydti.fawe.util.StringMan; import com.sk89q.minecraft.util.commands.Command; @@ -77,14 +80,22 @@ public class AnvilCommands { * @param * @return */ - public static > T runWithWorld(Player player, String folder, T filter) { + public static > T runWithWorld(Player player, String folder, T filter, boolean force) { + boolean copy = false; if (FaweAPI.getWorld(folder) != null) { - BBC.WORLD_IS_LOADED.send(player); - return null; + if (!force) { + BBC.WORLD_IS_LOADED.send(player); + return null; + } + copy = true; } FaweQueue defaultQueue = SetQueue.IMP.getNewQueue(folder, true, false); MCAQueue queue = new MCAQueue(folder, defaultQueue.getSaveFolder(), defaultQueue.hasSky()); - return queue.filterWorld(filter); + if (copy) { + return queue.filterCopy(filter, true); + } else { + return queue.filterWorld(filter); + } } /** @@ -132,7 +143,7 @@ public class AnvilCommands { max = 4 ) @CommandPermissions("worldedit.anvil.replaceall") - public void replaceAll(Player player, String folder, @Optional String from, String to, @Switch('d') boolean useData) throws WorldEditException { + public void replaceAll(Player player, String folder, @Optional String from, String to, @Switch('d') boolean useData, @Switch('f') boolean force) throws WorldEditException { final FaweBlockMatcher matchFrom; if (from == null) { matchFrom = FaweBlockMatcher.NOT_AIR; @@ -144,21 +155,60 @@ public class AnvilCommands { } final FaweBlockMatcher matchTo = FaweBlockMatcher.setBlocks(worldEdit.getBlocks(player, to, true)); ReplaceSimpleFilter filter = new ReplaceSimpleFilter(matchFrom, matchTo); - ReplaceSimpleFilter result = runWithWorld(player, folder, filter); + ReplaceSimpleFilter result = runWithWorld(player, folder, filter, force); if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal())); } @Command( - aliases = {"deleteallold"}, + aliases = {"deleteallunvisited", "delunvisited" }, usage = " [file-age=60000]", - desc = "Delete all chunks which haven't been occupied for `age-ticks` and have been accessed since `file-age` (ms) after creation", + desc = "Delete all chunks which haven't been occupied for `age-ticks` (20t = 1s) and \n" + + "Have not been accessed since `file-duration` (ms) after creation and\n" + + "Have not been used in the past `chunk-inactivity` (ms)" + + "The auto-save interval is the recommended value for `file-duration` and `chunk-inactivity`", min = 2, max = 3 ) - @CommandPermissions("worldedit.anvil.deleteallold") - public void deleteAllOld(Player player, String folder, int inhabitedTicks, @Optional("60000") int fileAgeMillis, @Switch('f') boolean force) throws WorldEditException { - DeleteUninhabitedFilter filter = new DeleteUninhabitedFilter(fileAgeMillis, inhabitedTicks); - DeleteUninhabitedFilter result = runWithWorld(player, folder, filter); + @CommandPermissions("worldedit.anvil.deleteallunvisited") + public void deleteAllUnvisited(Player player, String folder, int inhabitedTicks, @Optional("60000") int fileDurationMillis, @Switch('f') boolean force) throws WorldEditException { + long chunkInactivityMillis = fileDurationMillis; // Use same value for now + DeleteUninhabitedFilter filter = new DeleteUninhabitedFilter(fileDurationMillis, inhabitedTicks, chunkInactivityMillis); + DeleteUninhabitedFilter result = runWithWorld(player, folder, filter, force); + if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal())); + } + + @Command( + aliases = {"deletealloldregions", "deloldreg" }, + usage = "