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.
This commit is contained in:
LexManos 2012-12-23 23:31:13 -08:00
parent 0562fd85b9
commit dedc02fa22
2 changed files with 116 additions and 9 deletions

View file

@ -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);

View file

@ -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);