Fixes #2526: Using 5-bit for 0-32 is not sufficient. Rewrote packet for syncing cables to clients to use an easier to deal with format while still saving space in the normal case (2 sides connected to a cable).

(cherry picked from commit 6b90c70755)
This commit is contained in:
Sebastian Hartte 2016-10-30 00:06:10 +08:00 committed by xsun2001
parent f7d904c253
commit c5bf7f6be3
1 changed files with 40 additions and 41 deletions

View File

@ -40,6 +40,7 @@ import appeng.items.parts.ItemMultiPart;
import appeng.me.GridAccessException;
import appeng.parts.AEBasePart;
import appeng.util.Platform;
import net.minecraftforge.common.util.ForgeDirection;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
@ -466,10 +467,11 @@ public class PartCable extends AEBasePart implements IPartCable
@Override
public void writeToStream( final ByteBuf data ) throws IOException
{
int cs = 0;
int sideOut = 0;
int flags = 0;
boolean[] writeSide = new boolean[ForgeDirection.VALID_DIRECTIONS.length];
int[] channelsPerSide = new int[ForgeDirection.VALID_DIRECTIONS.length];
final IGridNode n = this.getGridNode();
IGridNode n = this.getGridNode();
if( n != null )
{
for( final ForgeDirection thisSide : ForgeDirection.VALID_DIRECTIONS )
@ -479,17 +481,12 @@ public class PartCable extends AEBasePart implements IPartCable
{
if( part.getGridNode() != null )
{
writeSide[thisSide.ordinal()] = true;
final IReadOnlyCollection<IGridConnection> set = part.getGridNode().getConnections();
for( final IGridConnection gc : set )
{
if( this.getProxy().getNode().hasFlag( GridFlags.DENSE_CAPACITY ) && gc.getOtherSide( this.getProxy().getNode() ).hasFlag( GridFlags.DENSE_CAPACITY ) )
{
sideOut |= ( gc.getUsedChannels() / 4 ) << ( 4 * thisSide.ordinal() );
}
else
{
sideOut |= ( gc.getUsedChannels() ) << ( 4 * thisSide.ordinal() );
}
channelsPerSide[thisSide.ordinal()] = gc.getUsedChannels();
}
}
}
@ -500,18 +497,9 @@ public class PartCable extends AEBasePart implements IPartCable
final ForgeDirection side = gc.getDirection( n );
if( side != ForgeDirection.UNKNOWN )
{
final boolean isTier2a = this.getProxy().getNode().hasFlag( GridFlags.DENSE_CAPACITY );
final boolean isTier2b = gc.getOtherSide( this.getProxy().getNode() ).hasFlag( GridFlags.DENSE_CAPACITY );
if( isTier2a && isTier2b )
{
sideOut |= ( gc.getUsedChannels() / 4 ) << ( 4 * side.ordinal() );
}
else
{
sideOut |= gc.getUsedChannels() << ( 4 * side.ordinal() );
}
cs |= ( 1 << side.ordinal() );
writeSide[side.ordinal()] = true;
channelsPerSide[side.ordinal()] = gc.getUsedChannels();
flags |= ( 1 << side.ordinal() );
}
}
}
@ -520,7 +508,7 @@ public class PartCable extends AEBasePart implements IPartCable
{
if( this.getProxy().getEnergy().isNetworkPowered() )
{
cs |= ( 1 << ForgeDirection.UNKNOWN.ordinal() );
flags |= ( 1 << ForgeDirection.UNKNOWN.ordinal() );
}
}
catch( final GridAccessException e )
@ -528,16 +516,21 @@ public class PartCable extends AEBasePart implements IPartCable
// aww...
}
data.writeByte( (byte) cs );
data.writeInt( sideOut );
data.writeByte( (byte) flags );
// Only write the used channels for sides where we have a part or another cable
for( int i = 0; i < writeSide.length; i++ )
{
if( writeSide[i] )
{
data.writeByte( channelsPerSide[i] );
}
}
}
@Override
public boolean readFromStream( final ByteBuf data ) throws IOException
{
final int cs = data.readByte();
final int sideOut = data.readInt();
int cs = data.readByte();
final EnumSet<ForgeDirection> myC = this.getConnections().clone();
final boolean wasPowered = this.powered;
this.powered = false;
@ -545,16 +538,6 @@ public class PartCable extends AEBasePart implements IPartCable
for( final ForgeDirection d : ForgeDirection.values() )
{
if( d != ForgeDirection.UNKNOWN )
{
final int ch = ( sideOut >> ( d.ordinal() * 4 ) ) & 0xF;
if( ch != this.getChannelsOnSide()[d.ordinal()] )
{
channelsChanged = true;
this.getChannelsOnSide()[d.ordinal()] = ch;
}
}
if( d == ForgeDirection.UNKNOWN )
{
final int id = 1 << d.ordinal();
@ -565,8 +548,8 @@ public class PartCable extends AEBasePart implements IPartCable
}
else
{
final int id = 1 << d.ordinal();
if( id == ( cs & id ) )
boolean conOnSide = ( cs & ( 1 << d.ordinal() ) ) != 0;
if( conOnSide )
{
this.getConnections().add( d );
}
@ -574,6 +557,22 @@ public class PartCable extends AEBasePart implements IPartCable
{
this.getConnections().remove( d );
}
int ch = 0;
// Only read channels if there's a part on this side or a cable connection
// This works only because cables are always read *last* from the packet update for
// a cable bus
if( conOnSide || getHost().getPart( d ) != null )
{
ch = ( (int) data.readByte() ) & 0xFF;
}
if( ch != this.channelsOnSide[d.ordinal()] )
{
channelsChanged = true;
this.channelsOnSide[d.ordinal()] = ch;
}
}
}