From 9db51fbbc4985383d1f92291872b0a8cb3d40f21 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Sun, 21 Aug 2016 20:22:46 +1000 Subject: [PATCH] Add world compression option --- .../fawe/bukkit/v1_10/BukkitMain_110.java | 52 +++++++++++++++++++ .../java/com/boydti/fawe/config/Settings.java | 17 ++++-- .../com/boydti/fawe/jnbt/anvil/MCAFile.java | 23 +------- .../com/boydti/fawe/util/ReflectionUtils.java | 2 +- .../java/com/sk89q/worldedit/EditSession.java | 2 +- 5 files changed, 69 insertions(+), 27 deletions(-) diff --git a/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitMain_110.java b/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitMain_110.java index d3664fed..e04bdfe6 100644 --- a/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitMain_110.java +++ b/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitMain_110.java @@ -2,6 +2,18 @@ package com.boydti.fawe.bukkit.v1_10; import com.boydti.fawe.bukkit.ABukkitMain; import com.boydti.fawe.bukkit.v0.BukkitQueue_0; +import com.boydti.fawe.config.Settings; +import com.boydti.fawe.util.ReflectionUtils; +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.zip.Deflater; +import java.util.zip.DeflaterOutputStream; +import net.minecraft.server.v1_10_R1.RegionFile; +import net.minecraft.server.v1_10_R1.RegionFileCache; public class BukkitMain_110 extends ABukkitMain { @Override @@ -9,4 +21,44 @@ public class BukkitMain_110 extends ABukkitMain { return new BukkitQueue_1_10(world); } + public BukkitMain_110() { + try { + ReflectionUtils.setFailsafeFieldValue(RegionFileCache.class.getDeclaredField("a"), null, new ConcurrentHashMap() { + @Override + public RegionFile get(Object key) { + RegionFile existing = super.get(key); + if (existing != null) { + return existing; + } + File file = (File) key; + if (!file.exists()) { + file.getParentFile().mkdirs(); + } + if (size() >= 256) { + RegionFileCache.a(); + } + RegionFile regionFile = new RegionFile(file) { + @Override + public DataOutputStream b(final int i, final int j) { + if (i < 0 || i >= 32 || j < 0 || j >= 32) { + return null; + } + return new DataOutputStream(new BufferedOutputStream(new DeflaterOutputStream(new ByteArrayOutputStream() { + @Override + public void close() throws IOException { + a(i, j, this.buf, this.count); + } + }, new Deflater(Settings.EXPERIMENTAL.WORLD_COMPRESSION)))); + } + }; + put(file, regionFile); + return regionFile; + } + }); + ; + } catch (Throwable e) { + e.printStackTrace(); + } + } + } \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/config/Settings.java b/core/src/main/java/com/boydti/fawe/config/Settings.java index 5160186f..70b3d5d9 100644 --- a/core/src/main/java/com/boydti/fawe/config/Settings.java +++ b/core/src/main/java/com/boydti/fawe/config/Settings.java @@ -185,9 +185,6 @@ public class Settings extends Config { }) public static int DISCARD_AFTER_MS = 60000; - @Comment("Certain doom!") - public static boolean EXPERIMENTAL_UNSTABLE_DO_NOT_ENABLE_ULTRA_SUPER_FAST_WORLD_CORRUPTING_AWESOME_DIRECT_ANVIL_QUEUE_MODE = false; - public static class PROGRESS { @Comment("Display constant titles about the progress of a user's edit") public static boolean DISPLAY = false; @@ -196,6 +193,20 @@ public class Settings extends Config { } } + @Comment("Experimental options") + public static class EXPERIMENTAL { + @Comment({ + "Directly modify the region files:", + " - May corrupt world if in use" + }) + public static boolean ANVIL_QUEUE_MODE = false; + @Comment({ + "Set the default world compression", + " - Only supports Bukkit 1.10 right now" + }) + public static int WORLD_COMPRESSION = -1; + } + public static class WEB { @Comment("I am already hosting a web interface for you here") public static String URL = "http://empcraft.com/fawe/"; diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAFile.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAFile.java index c6b624da..894bb4b2 100644 --- a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAFile.java +++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAFile.java @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import java.util.zip.Inflater; @@ -224,7 +223,7 @@ public class MCAFile { } ByteArrayOutputStream baos = new ByteArrayOutputStream(0); fieldBuf4.set(baos, buffer3); - DeflaterOutputStream deflater = new DeflaterOutputStream(baos, new Deflater(9), 1, true); + DeflaterOutputStream deflater = new DeflaterOutputStream(baos, new Deflater(Settings.EXPERIMENTAL.WORLD_COMPRESSION), 1, true); fieldBuf5.set(deflater, buffer2); BufferedOutputStream bos = new BufferedOutputStream(deflater, 1); fieldBuf6.set(bos, buffer1); @@ -353,25 +352,5 @@ public class MCAFile { } catch (Throwable e) { e.printStackTrace(); } - // TODO write header - } - - public static void main(String[] args) throws Exception { - // io benchmark - File folder = new File("../../mc/world/region"); - long start = System.nanoTime(); - final AtomicInteger count = new AtomicInteger(); - final int id = 1; -// for (File file : folder.listFiles()) { - { // Testing read/write - File file = new File(folder, "r.-2.-3.mca"); - final MCAFile mca = new MCAFile(null, file); - MCAChunk chunk = mca.getChunk(29, 30); - System.out.println("Block ID: " + chunk.getBlockCombinedId(0, 0, 0)); - chunk.setBlock(0,0,0, 5); - mca.flush(); - } - long diff = System.nanoTime() - start; - System.out.println(diff / 1000000d); // Time diff } } diff --git a/core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java b/core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java index de25643f..eecf4278 100644 --- a/core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java +++ b/core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java @@ -130,7 +130,7 @@ public class ReflectionUtils { return ReflectionFactory.getReflectionFactory().newConstructorAccessor(enumClass.getDeclaredConstructor(parameterTypes)); } - private static void setFailsafeFieldValue(Field field, Object target, Object value) + public static void setFailsafeFieldValue(Field field, Object target, Object value) throws NoSuchFieldException, IllegalAccessException { // let's make the field accessible diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index f3c6c3f7..7b60d3de 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -255,7 +255,7 @@ public class EditSession implements Extent { this.originalLimit = limit; this.limit = limit.copy(); this.queue = SetQueue.IMP.getNewQueue(Fawe.imp().getWorldName(world), fastmode, autoQueue); - if (Settings.QUEUE.EXPERIMENTAL_UNSTABLE_DO_NOT_ENABLE_ULTRA_SUPER_FAST_WORLD_CORRUPTING_AWESOME_DIRECT_ANVIL_QUEUE_MODE) { + if (Settings.EXPERIMENTAL.ANVIL_QUEUE_MODE) { this.queue = new MCAQueue(queue); } queue.addEditSession(this);