From dedc02fa22b90dd6ebee15ba8b2e4bea9dd03894 Mon Sep 17 00:00:00 2001 From: LexManos Date: Sun, 23 Dec 2012 23:31:13 -0800 Subject: [PATCH] Move chunk compression to the network thread in Packet 51 and 56 This will reduce the server load considerably by doing the chunk data compression in writePacketData, which will be run from the network thread. The chunk compression can easily use 1/4th of the overall server thread CPU time if someone is exploring much, especially when moving quickly (e.g. with quantum leggings). Player, this is how it's properly done. --- .../packet/Packet51MapChunk.java.patch | 58 +++++++++++++--- .../packet/Packet56MapChunks.java.patch | 67 +++++++++++++++++++ 2 files changed, 116 insertions(+), 9 deletions(-) create mode 100644 patches/minecraft/net/minecraft/network/packet/Packet56MapChunks.java.patch diff --git a/patches/minecraft/net/minecraft/network/packet/Packet51MapChunk.java.patch b/patches/minecraft/net/minecraft/network/packet/Packet51MapChunk.java.patch index c1e312382..c42cf84df 100644 --- a/patches/minecraft/net/minecraft/network/packet/Packet51MapChunk.java.patch +++ b/patches/minecraft/net/minecraft/network/packet/Packet51MapChunk.java.patch @@ -1,16 +1,56 @@ --- ../src_base/minecraft/net/minecraft/network/packet/Packet51MapChunk.java +++ ../src_work/minecraft/net/minecraft/network/packet/Packet51MapChunk.java -@@ -103,6 +103,13 @@ +@@ -57,16 +57,19 @@ + this.zCh = par1Chunk.zPosition; + this.includeInitialize = par2; + Packet51MapChunkData var4 = getMapChunkData(par1Chunk, par2, par3); +- Deflater var5 = new Deflater(-1); + this.yChMax = var4.field_74581_c; + this.yChMin = var4.field_74580_b; +- ++ this.field_73596_g = var4.field_74582_a; ++ } ++ ++ private void deflate() ++ { ++ Deflater var5 = new Deflater(-1); + try + { +- this.field_73596_g = var4.field_74582_a; +- var5.setInput(var4.field_74582_a, 0, var4.field_74582_a.length); ++ var5.setInput(field_73596_g, 0, field_73596_g.length); + var5.finish(); +- this.chunkData = new byte[var4.field_74582_a.length]; ++ this.chunkData = new byte[field_73596_g.length]; + this.tempLength = var5.deflate(this.chunkData); + } + finally +@@ -95,13 +98,16 @@ + par1DataInputStream.readFully(temp, 0, this.tempLength); + int var2 = 0; + int var3; ++ int msb = 0; //BugFix: MC does not read the MSB array from the packet properly, causing issues for servers that use blocks > 256 + + for (var3 = 0; var3 < 16; ++var3) + { + var2 += this.yChMin >> var3 & 1; ++ msb += this.yChMax >> var3 & 1; + } var3 = 12288 * var2; ++ var3 += 2048 * msb; -+ int msb = 0; //BugFix: MC does not read the MSB array from the packet properly, causing issues for servers that use blocks > 256 -+ for (int x = 0; x < 16; x++) -+ { -+ msb += (yChMax >> x) & 1; -+ } -+ var3 += (2048 * msb); -+ if (this.includeInitialize) { - var3 += 256; +@@ -131,6 +137,11 @@ + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException + { ++ if (chunkData == null) ++ { ++ deflate(); ++ } ++ + par1DataOutputStream.writeInt(this.xCh); + par1DataOutputStream.writeInt(this.zCh); + par1DataOutputStream.writeBoolean(this.includeInitialize); diff --git a/patches/minecraft/net/minecraft/network/packet/Packet56MapChunks.java.patch b/patches/minecraft/net/minecraft/network/packet/Packet56MapChunks.java.patch new file mode 100644 index 000000000..d6baee920 --- /dev/null +++ b/patches/minecraft/net/minecraft/network/packet/Packet56MapChunks.java.patch @@ -0,0 +1,67 @@ +--- ../src_base/minecraft/net/minecraft/network/packet/Packet56MapChunks.java ++++ ../src_work/minecraft/net/minecraft/network/packet/Packet56MapChunks.java +@@ -22,6 +22,7 @@ + private int field_73585_g; + private boolean field_92024_h; + private static byte[] field_73591_h = new byte[0]; ++ private int maxLen = 0; + + public Packet56MapChunks() {} + +@@ -40,15 +41,6 @@ + { + Chunk var5 = (Chunk)par1List.get(var4); + Packet51MapChunkData var6 = Packet51MapChunk.getMapChunkData(var5, true, 65535); +- +- if (field_73591_h.length < var3 + var6.field_74582_a.length) +- { +- byte[] var7 = new byte[var3 + var6.field_74582_a.length]; +- System.arraycopy(field_73591_h, 0, var7, 0, field_73591_h.length); +- field_73591_h = var7; +- } +- +- System.arraycopy(var6.field_74582_a, 0, field_73591_h, var3, var6.field_74582_a.length); + var3 += var6.field_74582_a.length; + this.field_73589_c[var4] = var5.xPosition; + this.field_73586_d[var4] = var5.zPosition; +@@ -57,13 +49,26 @@ + this.field_73584_f[var4] = var6.field_74582_a; + } + ++ maxLen = var3; ++ } ++ ++ private void deflate() ++ { ++ byte[] data = new byte[maxLen]; ++ int offset = 0; ++ for (int x = 0; x < field_73584_f.length; x++) ++ { ++ System.arraycopy(field_73584_f[x], 0, data, offset, field_73584_f[x].length); ++ offset += field_73584_f[x].length; ++ } ++ + Deflater var11 = new Deflater(-1); + + try + { +- var11.setInput(field_73591_h, 0, var3); ++ var11.setInput(data, 0, maxLen); + var11.finish(); +- this.field_73587_e = new byte[var3]; ++ this.field_73587_e = new byte[maxLen]; + this.field_73585_g = var11.deflate(this.field_73587_e); + } + finally +@@ -146,6 +151,11 @@ + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException + { ++ if (field_73587_e == null) ++ { ++ deflate(); ++ } ++ + par1DataOutputStream.writeShort(this.field_73589_c.length); + par1DataOutputStream.writeInt(this.field_73585_g); + par1DataOutputStream.writeBoolean(this.field_92024_h);