Skip to content

Commit

Permalink
Fixes #1077 Hotfix: Opening a terminal will not crash as fast anymore…
Browse files Browse the repository at this point in the history
… in systems with many items.
  • Loading branch information
thatsIch committed Mar 23, 2015
1 parent f138a68 commit a1f43ff
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 103 deletions.
89 changes: 45 additions & 44 deletions src/main/java/appeng/core/sync/AppEngPacketHandlerBase.java
Expand Up @@ -18,6 +18,7 @@

package appeng.core.sync;


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
Expand Down Expand Up @@ -50,101 +51,101 @@
import appeng.core.sync.packets.PacketTransitionEffect;
import appeng.core.sync.packets.PacketValueConfig;


public class AppEngPacketHandlerBase
{
private static final Map<Class<? extends AppEngPacket>, PacketTypes> REVERSE_LOOKUP = new HashMap<Class<? extends AppEngPacket>, AppEngPacketHandlerBase.PacketTypes>();

public static final Map<Class, PacketTypes> REVERSE_LOOKUP = new HashMap<Class, AppEngPacketHandlerBase.PacketTypes>();

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<? extends AppEngPacket> packetClass;
private final Constructor<? extends AppEngPacket> packetConstructor;

private PacketTypes(Class c) {
this.pc = c;
PacketTypes( Class<? extends AppEngPacket> c )
{
this.packetClass = c;

Constructor x = null;
Constructor<? extends AppEngPacket> 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<? extends AppEngPacket> c )
{
return (values())[id];
return REVERSE_LOOKUP.get( c );
}

public static PacketTypes getID(Class<? extends AppEngPacket> c)
public AppEngPacket parsePacket( ByteBuf in ) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
return AppEngPacketHandlerBase.REVERSE_LOOKUP.get( c );
return this.packetConstructor.newInstance( in );
}

}

}
130 changes: 71 additions & 59 deletions src/main/java/appeng/core/sync/packets/PacketMEInventoryUpdate.java
Expand Up @@ -18,6 +18,7 @@

package appeng.core.sync.packets;


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
Expand All @@ -26,6 +27,7 @@
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;
Expand All @@ -48,82 +50,115 @@
import appeng.core.sync.network.INetworkInfo;
import appeng.util.item.AEItemStack;


public class PacketMEInventoryUpdate extends AppEngPacket
{
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.
@Nullable
private final List<IAEItemStack> list;
// output...
final private byte ref;
final private ByteBuf data;
final private GZIPOutputStream compressFrame;
private final byte ref;

int writtenBytes = 0;
@Nullable
private final ByteBuf data;
@Nullable
private final GZIPOutputStream compressFrame;

boolean empty = true;

// input.
final List<IAEItemStack> list;
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<IAEItemStack>();
this.ref = stream.readByte();

// 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();

// 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()
{
Expand All @@ -134,46 +169,24 @@ public FMLProxyPacket getProxy()
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;
return 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();
Expand All @@ -191,5 +204,4 @@ public boolean isEmpty()
{
return this.empty;
}

}

0 comments on commit a1f43ff

Please sign in to comment.