|
| 1 | +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| 2 | +From: HaHaWTH <id_cn00@outlook.com> |
| 3 | +Date: Fri, 5 Apr 2024 08:14:28 +0800 |
| 4 | +Subject: [PATCH] zstd-compression |
| 5 | + |
| 6 | + |
| 7 | +diff --git a/pom.xml b/pom.xml |
| 8 | +index bfea35121ca986b396defe431d23592014cc5d48..f6ed279354c90e6daf631717f7ad2d63a87bcbc0 100644 |
| 9 | +--- a/pom.xml |
| 10 | ++++ b/pom.xml |
| 11 | +@@ -157,6 +157,14 @@ |
| 12 | + <scope>compile</scope> |
| 13 | + </dependency> |
| 14 | + <!-- Reaper end --> |
| 15 | ++ |
| 16 | ++ <dependency> |
| 17 | ++ <groupId>com.github.luben</groupId> |
| 18 | ++ <artifactId>zstd-jni</artifactId> |
| 19 | ++ <version>1.5.6-2</version> |
| 20 | ++ <scope>compile</scope> |
| 21 | ++ </dependency> |
| 22 | ++ |
| 23 | + <!-- Reaper start - Add FastUUID --> |
| 24 | + <dependency> |
| 25 | + <groupId>com.eatthepath</groupId> |
| 26 | +diff --git a/src/main/java/com/github/ruviolence/reaper/BeastConfig.java b/src/main/java/com/github/ruviolence/reaper/BeastConfig.java |
| 27 | +index ca3a6c0bf6e0b1849870424bcff2dc430c1714ca..5ed1e87ab91adcf7f49025747c8567e093f551a2 100644 |
| 28 | +--- a/src/main/java/com/github/ruviolence/reaper/BeastConfig.java |
| 29 | ++++ b/src/main/java/com/github/ruviolence/reaper/BeastConfig.java |
| 30 | +@@ -1,12 +1,7 @@ |
| 31 | + package com.github.ruviolence.reaper; |
| 32 | + |
| 33 | + import com.google.common.base.Throwables; |
| 34 | +-import net.minecraft.server.DispenserRegistry; |
| 35 | +-import net.minecraft.server.EntityPlayer; |
| 36 | +-import net.minecraft.server.MathHelper; |
| 37 | +-import net.minecraft.server.MinecraftServer; |
| 38 | +-import net.minecraft.server.Packet; |
| 39 | +-import net.minecraft.server.ReaperLightingQueue; |
| 40 | ++import net.minecraft.server.*; |
| 41 | + import org.bukkit.Bukkit; |
| 42 | + import org.bukkit.command.Command; |
| 43 | + import org.bukkit.configuration.ConfigurationSection; |
| 44 | +@@ -141,6 +136,19 @@ public class BeastConfig { |
| 45 | + private static void dynamicViewDistance() { |
| 46 | + dynamicViewDistance = getBoolean("dynamic-view-distance", true); |
| 47 | + } |
| 48 | ++ public static boolean zstdCompression; |
| 49 | ++ private static void zstdCompression() { |
| 50 | ++ zstdCompression = getBoolean("zstd-compression", false); |
| 51 | ++ } |
| 52 | ++ public static int chunkCompressionLevel = -1; |
| 53 | ++ private static void chunkCompressionLevel() { |
| 54 | ++ chunkCompressionLevel = getInt("compression.chunk-compression-level", -1); |
| 55 | ++ |
| 56 | ++ if (chunkCompressionLevel < -1 || chunkCompressionLevel > 9) { |
| 57 | ++ chunkCompressionLevel = -1; |
| 58 | ++ } |
| 59 | ++ RegionFile.deflater.setLevel(chunkCompressionLevel); |
| 60 | ++ } |
| 61 | + |
| 62 | + public static int portalTravelCacheLife; |
| 63 | + public static boolean portalTravelInstantExpire; |
| 64 | +diff --git a/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java b/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java |
| 65 | +index 8b5aeb1b02eeb24b29fede44b625587826052f90..92b88432d87eeb94257dcebae4e71b05600a76c1 100644 |
| 66 | +--- a/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java |
| 67 | ++++ b/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java |
| 68 | +@@ -1,5 +1,9 @@ |
| 69 | + package net.minecraft.server; |
| 70 | + |
| 71 | ++import com.github.luben.zstd.ZstdInputStream; |
| 72 | ++import com.github.luben.zstd.ZstdOutputStream; |
| 73 | ++import com.github.ruviolence.reaper.BeastConfig; |
| 74 | ++ |
| 75 | + import java.io.BufferedInputStream; |
| 76 | + import java.io.BufferedOutputStream; |
| 77 | + import java.io.DataInput; |
| 78 | +@@ -15,7 +19,7 @@ import java.util.zip.GZIPOutputStream; |
| 79 | + public class NBTCompressedStreamTools { |
| 80 | + |
| 81 | + public static NBTTagCompound a(InputStream inputstream) throws IOException { |
| 82 | +- DataInputStream datainputstream = new DataInputStream(new BufferedInputStream(new GZIPInputStream(inputstream))); |
| 83 | ++ DataInputStream datainputstream = new DataInputStream(new BufferedInputStream(getCompressionInputStream(inputstream))); |
| 84 | + |
| 85 | + NBTTagCompound nbttagcompound; |
| 86 | + |
| 87 | +@@ -29,7 +33,7 @@ public class NBTCompressedStreamTools { |
| 88 | + } |
| 89 | + |
| 90 | + public static void a(NBTTagCompound nbttagcompound, OutputStream outputstream) throws IOException { |
| 91 | +- DataOutputStream dataoutputstream = new DataOutputStream(new BufferedOutputStream(new GZIPOutputStream(outputstream))); |
| 92 | ++ DataOutputStream dataoutputstream = new DataOutputStream(new BufferedOutputStream(getCompressionOutputStream(outputstream))); |
| 93 | + |
| 94 | + try { |
| 95 | + a(nbttagcompound, (DataOutput) dataoutputstream); |
| 96 | +@@ -94,4 +98,44 @@ public class NBTCompressedStreamTools { |
| 97 | + } |
| 98 | + } |
| 99 | + } |
| 100 | ++ |
| 101 | ++ public static InputStream getCompressionInputStream(InputStream inputStream) throws IOException { |
| 102 | ++ if (BeastConfig.zstdCompression) { |
| 103 | ++ BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); |
| 104 | ++ if (!isGZipped(bufferedInputStream)) { |
| 105 | ++ return new ZstdInputStream(bufferedInputStream); |
| 106 | ++ } else { |
| 107 | ++ return new GZIPInputStream(bufferedInputStream); |
| 108 | ++ } |
| 109 | ++ } else { |
| 110 | ++ return new GZIPInputStream(inputStream); |
| 111 | ++ } |
| 112 | ++ } |
| 113 | ++ |
| 114 | ++ public static OutputStream getCompressionOutputStream(OutputStream outputStream) throws IOException { |
| 115 | ++ if (BeastConfig.zstdCompression) { |
| 116 | ++ return new ZstdOutputStream(outputStream, BeastConfig.chunkCompressionLevel); |
| 117 | ++ } else { |
| 118 | ++ return new GZIPOutputStream(outputStream) {{ |
| 119 | ++ def.setLevel(BeastConfig.chunkCompressionLevel); |
| 120 | ++ }}; |
| 121 | ++ } |
| 122 | ++ } |
| 123 | ++ |
| 124 | ++ public static boolean isGZipped(InputStream in) { |
| 125 | ++ if (!in.markSupported()) { |
| 126 | ++ in = new BufferedInputStream(in); |
| 127 | ++ } |
| 128 | ++ in.mark(2); |
| 129 | ++ int magic = 0; |
| 130 | ++ try { |
| 131 | ++ magic = in.read() & 0xff | ((in.read() << 8) & 0xff00); |
| 132 | ++ in.reset(); |
| 133 | ++ } catch (IOException e) { |
| 134 | ++ e.printStackTrace(System.err); |
| 135 | ++ return false; |
| 136 | ++ } |
| 137 | ++ return magic == GZIPInputStream.GZIP_MAGIC; |
| 138 | ++ } |
| 139 | ++// Beast end |
| 140 | + } |
| 141 | +diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java |
| 142 | +index 05bd5fe48889bc47eb347e941e7ec61f0b33d407..15118f81a4ad3a8c9e97797788c1219c132728b8 100644 |
| 143 | +--- a/src/main/java/net/minecraft/server/RegionFile.java |
| 144 | ++++ b/src/main/java/net/minecraft/server/RegionFile.java |
| 145 | +@@ -1,6 +1,9 @@ |
| 146 | + package net.minecraft.server; |
| 147 | + |
| 148 | + import com.destroystokyo.paper.exception.ServerInternalException; |
| 149 | ++import com.github.luben.zstd.ZstdInputStream; |
| 150 | ++import com.github.luben.zstd.ZstdOutputStream; |
| 151 | ++import com.github.ruviolence.reaper.BeastConfig; |
| 152 | + import com.google.common.collect.Lists; |
| 153 | + import java.io.BufferedInputStream; |
| 154 | + import java.io.BufferedOutputStream; |
| 155 | +@@ -167,6 +170,10 @@ public class RegionFile { |
| 156 | + abyte = new byte[j1 - 1]; |
| 157 | + this.c.read(abyte); |
| 158 | + return new DataInputStream(new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(abyte)))); |
| 159 | ++ } else if (b0 == 6) { |
| 160 | ++ abyte = new byte[j1 - 1]; |
| 161 | ++ this.c.read(abyte); |
| 162 | ++ return new DataInputStream(new BufferedInputStream(new ZstdInputStream(new ByteArrayInputStream(abyte)))); |
| 163 | + } else { |
| 164 | + return null; |
| 165 | + } |
| 166 | +@@ -271,7 +278,7 @@ public class RegionFile { |
| 167 | + private void a(int i, byte[] abyte, int j) throws IOException { |
| 168 | + this.c.seek((long) (i * 4096)); |
| 169 | + this.c.writeInt(j + 1); |
| 170 | +- this.c.writeByte(2); |
| 171 | ++ this.c.writeByte(BeastConfig.zstdCompression ? 6 : 2); |
| 172 | + this.c.write(abyte, 0, j); |
| 173 | + } |
| 174 | + |
| 175 | +@@ -474,6 +481,15 @@ public class RegionFile { |
| 176 | + // Paper start - apply dynamic compression |
| 177 | + int origLength = this.count; |
| 178 | + byte[] buf = this.buf; |
| 179 | ++ // Beast start |
| 180 | ++ if (BeastConfig.zstdCompression) { |
| 181 | ++ ByteArrayOutputStream out = new ByteArrayOutputStream(origLength); |
| 182 | ++ new ZstdOutputStream(this, BeastConfig.chunkCompressionLevel).write(buf, 0, origLength); |
| 183 | ++ byte[] outArray = out.toByteArray(); |
| 184 | ++ RegionFile.this.a(this.b, this.c, outArray, outArray.length); // Paper - change to bytes/length |
| 185 | ++ return; |
| 186 | ++ } |
| 187 | ++ // Beast end |
| 188 | + DirectByteArrayOutputStream out = compressData(buf, origLength); |
| 189 | + byte[] bytes = out.getBuffer(); |
| 190 | + int length = out.size(); |
| 191 | +@@ -483,7 +499,7 @@ public class RegionFile { |
| 192 | + } |
| 193 | + |
| 194 | + private static final byte[] compressionBuffer = new byte[1024 * 64]; // 64k fits most standard chunks input size even, ideally 1 pass through zlib |
| 195 | +- private static final java.util.zip.Deflater deflater = new java.util.zip.Deflater(); |
| 196 | ++ public static final java.util.zip.Deflater deflater = new java.util.zip.Deflater(); |
| 197 | + // since file IO is single threaded, no benefit to using per-region file buffers/synchronization, we can change that later if it becomes viable. |
| 198 | + private static DirectByteArrayOutputStream compressData(byte[] buf, int length) throws IOException { |
| 199 | + synchronized (deflater) { |
0 commit comments