Hey ma, look at my packet encoder!

This commit is contained in:
md_5 2013-06-29 16:07:41 +10:00
parent d2bde0b68f
commit 2332de0fda

View file

@ -1,4 +1,4 @@
From bb2577d18f5b7fd2e0582de1acd29825c3005276 Mon Sep 17 00:00:00 2001 From a05a6c78a40c45b5b882ccd9877b7fea231c83eb Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au> From: md_5 <md_5@live.com.au>
Date: Sun, 23 Jun 2013 16:32:51 +1000 Date: Sun, 23 Jun 2013 16:32:51 +1000
Subject: [PATCH] Netty Subject: [PATCH] Netty
@ -1417,16 +1417,18 @@ index 0000000..3adc8d6
+} +}
diff --git a/src/main/java/org/spigotmc/netty/PacketEncoder.java b/src/main/java/org/spigotmc/netty/PacketEncoder.java diff --git a/src/main/java/org/spigotmc/netty/PacketEncoder.java b/src/main/java/org/spigotmc/netty/PacketEncoder.java
new file mode 100644 new file mode 100644
index 0000000..e6a45d3 index 0000000..5b35ab0
--- /dev/null --- /dev/null
+++ b/src/main/java/org/spigotmc/netty/PacketEncoder.java +++ b/src/main/java/org/spigotmc/netty/PacketEncoder.java
@@ -0,0 +1,55 @@ @@ -0,0 +1,71 @@
+package org.spigotmc.netty; +package org.spigotmc.netty;
+ +
+import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufOutputStream; +import io.netty.buffer.ByteBufOutputStream;
+import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToByteEncoder; +import io.netty.channel.ChannelOutboundHandlerAdapter;
+import io.netty.channel.ChannelPromise;
+import io.netty.channel.MessageList;
+import java.io.DataOutputStream; +import java.io.DataOutputStream;
+import net.minecraft.server.Packet; +import net.minecraft.server.Packet;
+ +
@ -1434,11 +1436,9 @@ index 0000000..e6a45d3
+ * Netty encoder which takes a packet and encodes it, and adds a byte packet id + * Netty encoder which takes a packet and encodes it, and adds a byte packet id
+ * header. + * header.
+ */ + */
+public class PacketEncoder extends MessageToByteEncoder<Packet> +public class PacketEncoder extends ChannelOutboundHandlerAdapter
+{ +{
+ +
+ private ByteBuf outBuf;
+ private DataOutputStream dataOut;
+ private final NettyNetworkManager networkManager; + private final NettyNetworkManager networkManager;
+ +
+ public PacketEncoder(NettyNetworkManager networkManager) + public PacketEncoder(NettyNetworkManager networkManager)
@ -1447,32 +1447,48 @@ index 0000000..e6a45d3
+ } + }
+ +
+ @Override + @Override
+ public void encode(ChannelHandlerContext ctx, Packet msg, ByteBuf out) throws Exception + public void write(ChannelHandlerContext ctx, MessageList<Object> msgs, ChannelPromise promise) throws Exception
+ { + {
+ if ( outBuf == null ) + // Since we are writing in batches it can be useful to guess the size of our output to limit memcpy
+ int estimatedSize = 0;
+ for ( Object msg : msgs )
+ { + {
+ outBuf = ctx.alloc().buffer(); + if ( msg instanceof Packet )
+ {
+ estimatedSize += ( (Packet) msg ).a();
+ } else
+ {
+ throw new IllegalStateException( "Cannot send message of class " + msg.getClass() );
+ }
+ } + }
+ if ( dataOut == null ) + // Allocate an output buffer of estimated size
+ ByteBuf outBuf = ctx.alloc().buffer( estimatedSize );
+ // And a stream to which we can write this buffer to
+ DataOutputStream dataOut = new DataOutputStream( new ByteBufOutputStream( outBuf ) );
+
+ try
+ { + {
+ dataOut = new DataOutputStream( new ByteBufOutputStream( outBuf ) ); + // Iterate through all packets, this is safe as we know we will only ever get packets in the pipeline
+ } + for ( Packet packet : (MessageList<Packet>) (MessageList) msgs )
+ + {
+ out.writeByte( msg.n() ); + // Write packet ID
+ msg.a( dataOut ); + outBuf.writeByte( packet.n() );
+ + // Write packet data
+ networkManager.addWrittenBytes( outBuf.readableBytes() ); + packet.a( dataOut );
+ out.writeBytes( outBuf ); + }
+ outBuf.discardSomeReadBytes(); + // Add to the courtesy API providing number of written bytes
+ } + networkManager.addWrittenBytes( outBuf.readableBytes() );
+ + // Write down our single ByteBuf
+ @Override + ctx.write( outBuf, promise );
+ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception + } finally
+ {
+ if ( outBuf != null )
+ { + {
+ outBuf.release(); + // Very important that we do this for fast memory reclamation
+ outBuf = null; + msgs.recycle();
+ // Since we are now in the event loop, the bytes have been written, we can free them if this was not the case
+ if ( outBuf.refCnt() != 0 )
+ {
+ outBuf.release();
+ }
+ } + }
+ } + }
+} +}