From d44a0d5bd59d7bd85e365791a64fd49abc6d8dcc Mon Sep 17 00:00:00 2001 From: md_5 Date: Tue, 28 Jan 2014 20:32:07 +1100 Subject: [PATCH] Implement Threaded Bulk Chunk Compression diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java index 30bf8a7..178a4ba 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java @@ -6,7 +6,7 @@ import java.util.zip.DataFormatException; import java.util.zip.Deflater; import java.util.zip.Inflater; -public class PacketPlayOutMapChunkBulk extends Packet { +public class PacketPlayOutMapChunkBulk extends Packet implements org.spigotmc.Compressible { // Spigot private int[] a; private int[] b; @@ -174,7 +174,7 @@ public class PacketPlayOutMapChunkBulk extends Packet { } public void b(PacketDataSerializer packetdataserializer) throws IOException { // CraftBukkit - throws IOException - compress(); // CraftBukkit + // compress(); // CraftBukkit // Spigot - removed packetdataserializer.writeShort(this.a.length); packetdataserializer.writeInt(this.size); packetdataserializer.writeBoolean(this.h); diff --git a/src/main/java/net/minecraft/server/ServerConnectionChannel.java b/src/main/java/net/minecraft/server/ServerConnectionChannel.java index fb95be4..2875c94 100644 --- a/src/main/java/net/minecraft/server/ServerConnectionChannel.java +++ b/src/main/java/net/minecraft/server/ServerConnectionChannel.java @@ -1,15 +1,26 @@ package net.minecraft.server; +import com.google.common.util.concurrent.ThreadFactoryBuilder; // Spigot import net.minecraft.util.io.netty.channel.Channel; import net.minecraft.util.io.netty.channel.ChannelException; import net.minecraft.util.io.netty.channel.ChannelInitializer; import net.minecraft.util.io.netty.channel.ChannelOption; import net.minecraft.util.io.netty.handler.timeout.ReadTimeoutHandler; +// Spigot Start +import net.minecraft.util.io.netty.util.concurrent.DefaultEventExecutorGroup; +import net.minecraft.util.io.netty.util.concurrent.EventExecutorGroup; +import org.spigotmc.ChunkCompressor; +import org.spigotmc.SpigotConfig; +// Spigot End class ServerConnectionChannel extends ChannelInitializer { final ServerConnection a; - + // Spigot Start + private static final EventExecutorGroup threadPool = new DefaultEventExecutorGroup( SpigotConfig.compressionThreads, new ThreadFactoryBuilder().setNameFormat( "Chunk Compressor #%d" ).setDaemon( true ).build() ); + private static final ChunkCompressor chunkCompressor = new ChunkCompressor(); + // Spigot End + ServerConnectionChannel(ServerConnection serverconnection) { this.a = serverconnection; } @@ -27,7 +38,8 @@ class ServerConnectionChannel extends ChannelInitializer { ; } - channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)).addLast("legacy_query", new LegacyPingHandler(this.a)).addLast("splitter", new PacketSplitter()).addLast("decoder", new PacketDecoder()).addLast("prepender", new PacketPrepender()).addLast("encoder", new PacketEncoder()); + channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)).addLast("legacy_query", new LegacyPingHandler(this.a)).addLast("splitter", new PacketSplitter()).addLast("decoder", new PacketDecoder()).addLast("prepender", new PacketPrepender()).addLast("encoder", new PacketEncoder()) + .addLast( threadPool, "compressor", chunkCompressor ); // Spigot NetworkManager networkmanager = new NetworkManager(false); ServerConnection.a(this.a).add(networkmanager); diff --git a/src/main/java/org/spigotmc/ChunkCompressor.java b/src/main/java/org/spigotmc/ChunkCompressor.java new file mode 100644 index 0000000..50485d0 --- /dev/null +++ b/src/main/java/org/spigotmc/ChunkCompressor.java @@ -0,0 +1,21 @@ +package org.spigotmc; + +import net.minecraft.util.io.netty.channel.ChannelHandler; +import net.minecraft.util.io.netty.channel.ChannelHandlerContext; +import net.minecraft.util.io.netty.channel.ChannelOutboundHandlerAdapter; +import net.minecraft.util.io.netty.channel.ChannelPromise; + +@ChannelHandler.Sharable +public class ChunkCompressor extends ChannelOutboundHandlerAdapter +{ + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception + { + if ( msg instanceof Compressible ) + { + ( (Compressible) msg ).compress(); // TODO: Caching! + } + super.write( ctx, msg, promise ); + } +} diff --git a/src/main/java/org/spigotmc/Compressible.java b/src/main/java/org/spigotmc/Compressible.java new file mode 100644 index 0000000..f1cc789 --- /dev/null +++ b/src/main/java/org/spigotmc/Compressible.java @@ -0,0 +1,7 @@ +package org.spigotmc; + +public interface Compressible +{ + + void compress(); +} diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java index 552266b..ca41dd9 100755 --- a/src/main/java/org/spigotmc/SpigotConfig.java +++ b/src/main/java/org/spigotmc/SpigotConfig.java @@ -266,4 +266,11 @@ public class SpigotConfig { playerShuffle = getInt( "settings.player-shuffle", 0 ); } + + public static int compressionThreads; + private static void compressionThreads() + { + compressionThreads = getInt( "settings.compression-threads", 4 ); + Bukkit.getLogger().log( Level.INFO, "Using {0} threads for async chunk compression", compressionThreads ); + } } -- 1.8.3.2