From a1f43ff51a562f068f859b991c6545b337e3fd62 Mon Sep 17 00:00:00 2001 From: thatsIch Date: Mon, 23 Mar 2015 16:36:06 +0100 Subject: [PATCH] Fixes #1077 Hotfix: Opening a terminal will not crash as fast anymore in systems with many items. --- .../core/sync/AppEngPacketHandlerBase.java | 89 ++++++------ .../sync/packets/PacketMEInventoryUpdate.java | 134 ++++++++++-------- 2 files changed, 118 insertions(+), 105 deletions(-) diff --git a/src/main/java/appeng/core/sync/AppEngPacketHandlerBase.java b/src/main/java/appeng/core/sync/AppEngPacketHandlerBase.java index b8a6817d..bae32029 100644 --- a/src/main/java/appeng/core/sync/AppEngPacketHandlerBase.java +++ b/src/main/java/appeng/core/sync/AppEngPacketHandlerBase.java @@ -18,6 +18,7 @@ package appeng.core.sync; + import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; @@ -50,101 +51,101 @@ import appeng.core.sync.packets.PacketSwitchGuis; import appeng.core.sync.packets.PacketTransitionEffect; import appeng.core.sync.packets.PacketValueConfig; + public class AppEngPacketHandlerBase { + private static final Map, PacketTypes> REVERSE_LOOKUP = new HashMap, AppEngPacketHandlerBase.PacketTypes>(); - public static final Map REVERSE_LOOKUP = new HashMap(); public enum PacketTypes { - PACKET_COMPASS_REQUEST(PacketCompassRequest.class), + PACKET_COMPASS_REQUEST( PacketCompassRequest.class ), - PACKET_COMPASS_RESPONSE(PacketCompassResponse.class), + PACKET_COMPASS_RESPONSE( PacketCompassResponse.class ), - PACKET_INVENTORY_ACTION(PacketInventoryAction.class), + PACKET_INVENTORY_ACTION( PacketInventoryAction.class ), - PACKET_ME_INVENTORY_UPDATE(PacketMEInventoryUpdate.class), + PACKET_ME_INVENTORY_UPDATE( PacketMEInventoryUpdate.class ), - PACKET_CONFIG_BUTTON(PacketConfigButton.class), + PACKET_CONFIG_BUTTON( PacketConfigButton.class ), - PACKET_MULTIPART(PacketMultiPart.class), + PACKET_MULTIPART( PacketMultiPart.class ), - PACKET_PART_PLACEMENT(PacketPartPlacement.class), + PACKET_PART_PLACEMENT( PacketPartPlacement.class ), - PACKET_LIGHTNING(PacketLightning.class), + PACKET_LIGHTNING( PacketLightning.class ), - PACKET_MATTER_CANNON(PacketMatterCannon.class), + PACKET_MATTER_CANNON( PacketMatterCannon.class ), - PACKET_MOCK_EXPLOSION(PacketMockExplosion.class), + PACKET_MOCK_EXPLOSION( PacketMockExplosion.class ), - PACKET_VALUE_CONFIG(PacketValueConfig.class), + PACKET_VALUE_CONFIG( PacketValueConfig.class ), - PACKET_TRANSITION_EFFECT(PacketTransitionEffect.class), + PACKET_TRANSITION_EFFECT( PacketTransitionEffect.class ), - PACKET_PROGRESS_VALUE(PacketProgressBar.class), + PACKET_PROGRESS_VALUE( PacketProgressBar.class ), - PACKET_CLICK(PacketClick.class), + PACKET_CLICK( PacketClick.class ), - PACKET_NEW_STORAGE_DIMENSION(PacketNewStorageDimension.class), + PACKET_NEW_STORAGE_DIMENSION( PacketNewStorageDimension.class ), - PACKET_SWITCH_GUIS(PacketSwitchGuis.class), + PACKET_SWITCH_GUIS( PacketSwitchGuis.class ), - PACKET_SWAP_SLOTS(PacketSwapSlots.class), + PACKET_SWAP_SLOTS( PacketSwapSlots.class ), - PACKET_PATTERN_SLOT(PacketPatternSlot.class), + PACKET_PATTERN_SLOT( PacketPatternSlot.class ), - PACKET_RECIPE_NEI(PacketNEIRecipe.class), + PACKET_RECIPE_NEI( PacketNEIRecipe.class ), - PACKET_PARTIAL_ITEM(PacketPartialItem.class), + PACKET_PARTIAL_ITEM( PacketPartialItem.class ), - PACKET_CRAFTING_REQUEST(PacketCraftRequest.class), + PACKET_CRAFTING_REQUEST( PacketCraftRequest.class ), - PACKET_ASSEMBLER_ANIMATION(PacketAssemblerAnimation.class), + PACKET_ASSEMBLER_ANIMATION( PacketAssemblerAnimation.class ), - PACKET_COMPRESSED_NBT(PacketCompressedNBT.class), + PACKET_COMPRESSED_NBT( PacketCompressedNBT.class ), - PACKET_PAINTED_ENTITY(PacketPaintedEntity.class); + PACKET_PAINTED_ENTITY( PacketPaintedEntity.class ); - final public Class pc; - final public Constructor con; + private final Class packetClass; + private final Constructor packetConstructor; - private PacketTypes(Class c) { - this.pc = c; + PacketTypes( Class c ) + { + this.packetClass = c; - Constructor x = null; + Constructor x = null; try { - x = this.pc.getConstructor( ByteBuf.class ); + x = this.packetClass.getConstructor( ByteBuf.class ); } - catch (NoSuchMethodException ignored) + catch( NoSuchMethodException ignored ) { } - catch (SecurityException ignored) + catch( SecurityException ignored ) { } - this.con = x; - AppEngPacketHandlerBase.REVERSE_LOOKUP.put( this.pc, this ); + this.packetConstructor = x; + REVERSE_LOOKUP.put( this.packetClass, this ); - if ( this.con == null ) + if( this.packetConstructor == null ) throw new RuntimeException( "Invalid Packet Class, must be constructable on DataInputStream" ); } - public AppEngPacket parsePacket(ByteBuf in) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException + public static PacketTypes getPacket( int id ) { - return (AppEngPacket) this.con.newInstance( in ); + return ( values() )[id]; } - public static PacketTypes getPacket(int id) + public static PacketTypes getID( Class c ) { - return (values())[id]; + return REVERSE_LOOKUP.get( c ); } - public static PacketTypes getID(Class c) + public AppEngPacket parsePacket( ByteBuf in ) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - return AppEngPacketHandlerBase.REVERSE_LOOKUP.get( c ); + return this.packetConstructor.newInstance( in ); } - } - } diff --git a/src/main/java/appeng/core/sync/packets/PacketMEInventoryUpdate.java b/src/main/java/appeng/core/sync/packets/PacketMEInventoryUpdate.java index e41be271..6563ca27 100644 --- a/src/main/java/appeng/core/sync/packets/PacketMEInventoryUpdate.java +++ b/src/main/java/appeng/core/sync/packets/PacketMEInventoryUpdate.java @@ -18,6 +18,7 @@ package appeng.core.sync.packets; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -26,6 +27,7 @@ import java.util.LinkedList; import java.util.List; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; +import javax.annotation.Nullable; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; @@ -48,23 +50,31 @@ import appeng.core.sync.AppEngPacket; import appeng.core.sync.network.INetworkInfo; import appeng.util.item.AEItemStack; + public class PacketMEInventoryUpdate extends AppEngPacket { - - // output... - final private byte ref; - final private ByteBuf data; - final private GZIPOutputStream compressFrame; - - int writtenBytes = 0; - - boolean empty = true; + private static final int UNCOMPRESSED_PACKET_BYTE_LIMIT = 16 * 1024 * 1024; + private static final int OPERATION_BYTE_LIMIT = 2 * 1024; + private static final int TEMP_BUFFER_SIZE = 1024; + private static final int STREAM_MASK = 0xff; // input. - final List list; + @Nullable + private final List list; + // output... + private final byte ref; + + @Nullable + private final ByteBuf data; + @Nullable + private final GZIPOutputStream compressFrame; + + private int writtenBytes = 0; + private boolean empty = true; // automatic. - public PacketMEInventoryUpdate(final ByteBuf stream) throws IOException { + public PacketMEInventoryUpdate( final ByteBuf stream ) throws IOException + { this.data = null; this.compressFrame = null; this.list = new LinkedList(); @@ -72,25 +82,24 @@ public class PacketMEInventoryUpdate extends AppEngPacket // int originalBytes = stream.readableBytes(); - GZIPInputStream gzReader = new GZIPInputStream( new InputStream() { - + GZIPInputStream gzReader = new GZIPInputStream( new InputStream() + { @Override public int read() throws IOException { - if ( stream.readableBytes() <= 0 ) + if( stream.readableBytes() <= 0 ) return -1; - return stream.readByte() & 0xff; + return stream.readByte() & STREAM_MASK; } - } ); ByteBuf uncompressed = Unpooled.buffer( stream.readableBytes() ); - byte[] tmp = new byte[1024]; - while (gzReader.available() != 0) + byte[] tmp = new byte[TEMP_BUFFER_SIZE]; + while( gzReader.available() != 0 ) { int bytes = gzReader.read( tmp ); - if ( bytes > 0 ) + if( bytes > 0 ) uncompressed.writeBytes( tmp, 0, bytes ); } gzReader.close(); @@ -98,32 +107,58 @@ public class PacketMEInventoryUpdate extends AppEngPacket // int uncompressedBytes = uncompressed.readableBytes(); // AELog.info( "Receiver: " + originalBytes + " -> " + uncompressedBytes ); - while (uncompressed.readableBytes() > 0) + while( uncompressed.readableBytes() > 0 ) this.list.add( AEItemStack.loadItemStackFromPacket( uncompressed ) ); this.empty = this.list.isEmpty(); } + // api + public PacketMEInventoryUpdate() throws IOException + { + this( (byte) 0 ); + } + + // api + public PacketMEInventoryUpdate( byte ref ) throws IOException + { + this.ref = ref; + this.data = Unpooled.buffer( OPERATION_BYTE_LIMIT ); + this.data.writeInt( this.getPacketID() ); + this.data.writeByte( this.ref ); + + this.compressFrame = new GZIPOutputStream( new OutputStream() + { + @Override + public void write( int value ) throws IOException + { + PacketMEInventoryUpdate.this.data.writeByte( value ); + } + } ); + + this.list = null; + } + @Override - @SideOnly(Side.CLIENT) - public void clientPacketData(INetworkInfo network, AppEngPacket packet, EntityPlayer player) + @SideOnly( Side.CLIENT ) + public void clientPacketData( INetworkInfo network, AppEngPacket packet, EntityPlayer player ) { GuiScreen gs = Minecraft.getMinecraft().currentScreen; - if ( gs instanceof GuiCraftConfirm ) - ((GuiCraftConfirm) gs).postUpdate( this.list, this.ref ); + if( gs instanceof GuiCraftConfirm ) + ( (GuiCraftConfirm) gs ).postUpdate( this.list, this.ref ); - if ( gs instanceof GuiCraftingCPU ) - ((GuiCraftingCPU) gs).postUpdate( this.list, this.ref ); + if( gs instanceof GuiCraftingCPU ) + ( (GuiCraftingCPU) gs ).postUpdate( this.list, this.ref ); - if ( gs instanceof GuiMEMonitorable ) - ((GuiMEMonitorable) gs).postUpdate( this.list ); - - if ( gs instanceof GuiNetworkStatus ) - ((GuiNetworkStatus) gs).postUpdate( this.list ); + if( gs instanceof GuiMEMonitorable ) + ( (GuiMEMonitorable) gs ).postUpdate( this.list ); + if( gs instanceof GuiNetworkStatus ) + ( (GuiNetworkStatus) gs ).postUpdate( this.list ); } + @Nullable @Override public FMLProxyPacket getProxy() { @@ -134,46 +169,24 @@ public class PacketMEInventoryUpdate extends AppEngPacket this.configureWrite( this.data ); return super.getProxy(); } - catch (IOException e) + catch( IOException e ) { AELog.error( e ); } + return null; } - // api - public PacketMEInventoryUpdate() throws IOException { - this( (byte) 0 ); - } - - // api - public PacketMEInventoryUpdate(byte ref) throws IOException { - - this.data = Unpooled.buffer( 2048 ); - this.data.writeInt( this.getPacketID() ); - this.data.writeByte( this.ref = ref ); - - this.compressFrame = new GZIPOutputStream( new OutputStream() { - - @Override - public void write(int value) throws IOException - { - PacketMEInventoryUpdate.this.data.writeByte( value ); - } - - } ); - - this.list = null; - } - - public void appendItem(IAEItemStack is) throws IOException, BufferOverflowException + public void appendItem( IAEItemStack is ) throws IOException, BufferOverflowException { - ByteBuf tmp = Unpooled.buffer( 2048 ); + ByteBuf tmp = Unpooled.buffer( OPERATION_BYTE_LIMIT ); is.writeToPacket( tmp ); this.compressFrame.flush(); - if ( this.writtenBytes + tmp.readableBytes() > 2 * 1024 * 1024 ) // 2mb! + if( this.writtenBytes + tmp.readableBytes() > UNCOMPRESSED_PACKET_BYTE_LIMIT ) + { throw new BufferOverflowException(); + } else { this.writtenBytes += tmp.readableBytes(); @@ -191,5 +204,4 @@ public class PacketMEInventoryUpdate extends AppEngPacket { return this.empty; } - }