Skip to content

Commit b9c461f

Browse files
committed
Zstd compression
1 parent 3fc9fc2 commit b9c461f

File tree

1 file changed

+199
-0
lines changed

1 file changed

+199
-0
lines changed
+199
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
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

Comments
 (0)