Refactors grid connections (#3219)

Extracted all checks and subsequent updates to a factory method from the constructor.
Reordered checks to check for nulls before anything else.
Also existing connections before security breaks.
Fixes TileController#checkController() using the wrong position.
Added debug logging for failed connections.
Improved logging.
Inversed boolean so false no longer means security check passed.
Only issue a security break on SecurityConnectionException.
This commit is contained in:
yueh 2017-11-12 18:13:59 +01:00 committed by GitHub
parent ba9af94228
commit e0bf7223e0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 129 additions and 96 deletions

View file

@ -59,7 +59,7 @@ public class ApiGrid implements IGridHelper
Preconditions.checkNotNull( a );
Preconditions.checkNotNull( b );
return new GridConnection( a, b, AEPartLocation.INTERNAL );
return GridConnection.create( a, b, AEPartLocation.INTERNAL );
}
}

View file

@ -54,80 +54,11 @@ public class GridConnection implements IGridConnection, IPathItem
private AEPartLocation fromAtoB;
private GridNode sideB;
public GridConnection( final IGridNode aNode, final IGridNode bNode, final AEPartLocation fromAtoB ) throws FailedConnectionException
private GridConnection( final GridNode aNode, final GridNode bNode, final AEPartLocation fromAtoB )
{
final GridNode a = (GridNode) aNode;
final GridNode b = (GridNode) bNode;
if( Platform.securityCheck( a, b ) )
{
if( AEConfig.instance().isFeatureEnabled( AEFeature.LOG_SECURITY_AUDITS ) )
{
final DimensionalCoord aCoordinates = a.getGridBlock().getLocation();
final DimensionalCoord bCoordinates = b.getGridBlock().getLocation();
AELog.info( "Security audit 1 failed at [%s] belonging to player [id=%d]", aCoordinates.toString(), a.getPlayerID() );
AELog.info( "Security audit 2 failed at [%s] belonging to player [id=%d]", bCoordinates.toString(), b.getPlayerID() );
}
throw new SecurityConnectionException();
}
if( a == null || b == null )
{
throw new NullNodeConnectionException();
}
if( a.hasConnection( b ) || b.hasConnection( a ) )
{
final String aMachineClass = a.getGridBlock().getMachine().getClass().getSimpleName();
final String bMachineClass = b.getGridBlock().getMachine().getClass().getSimpleName();
final String aCoordinates = a.getGridBlock().getLocation().toString();
final String bCoordinates = b.getGridBlock().getLocation().toString();
throw new ExistingConnectionException( String.format( EXISTING_CONNECTION_MESSAGE, aMachineClass, aCoordinates, bMachineClass, bCoordinates,
fromAtoB ) );
}
this.sideA = a;
this.sideA = aNode;
this.fromAtoB = fromAtoB;
this.sideB = b;
if( b.getMyGrid() == null )
{
b.setGrid( a.getInternalGrid() );
}
else
{
if( a.getMyGrid() == null )
{
final GridPropagator gp = new GridPropagator( b.getInternalGrid() );
a.beginVisit( gp );
}
else if( b.getMyGrid() == null )
{
final GridPropagator gp = new GridPropagator( a.getInternalGrid() );
b.beginVisit( gp );
}
else if( this.isNetworkABetter( a, b ) )
{
final GridPropagator gp = new GridPropagator( a.getInternalGrid() );
b.beginVisit( gp );
}
else
{
final GridPropagator gp = new GridPropagator( b.getInternalGrid() );
a.beginVisit( gp );
}
}
// a connection was destroyed RE-PATH!!
final IPathingGrid p = this.sideA.getInternalGrid().getCache( IPathingGrid.class );
p.repath();
this.sideA.addConnection( this );
this.sideB.addConnection( this );
this.sideB = bNode;
}
private boolean isNetworkABetter( final GridNode a, final GridNode b )
@ -291,4 +222,81 @@ public class GridConnection implements IGridConnection, IPathItem
{
this.visitorIterationNumber = visitorIterationNumber;
}
public static GridConnection create( final IGridNode aNode, final IGridNode bNode, final AEPartLocation fromAtoB ) throws FailedConnectionException
{
if( aNode == null || bNode == null )
{
throw new NullNodeConnectionException();
}
final GridNode a = (GridNode) aNode;
final GridNode b = (GridNode) bNode;
if( a.hasConnection( b ) || b.hasConnection( a ) )
{
final String aMachineClass = a.getGridBlock().getMachine().getClass().getSimpleName();
final String bMachineClass = b.getGridBlock().getMachine().getClass().getSimpleName();
final String aCoordinates = a.getGridBlock().getLocation().toString();
final String bCoordinates = b.getGridBlock().getLocation().toString();
throw new ExistingConnectionException( String.format( EXISTING_CONNECTION_MESSAGE, aMachineClass, aCoordinates, bMachineClass, bCoordinates,
fromAtoB ) );
}
if( !Platform.securityCheck( a, b ) )
{
if( AEConfig.instance().isFeatureEnabled( AEFeature.LOG_SECURITY_AUDITS ) )
{
final DimensionalCoord aCoordinates = a.getGridBlock().getLocation();
final DimensionalCoord bCoordinates = b.getGridBlock().getLocation();
AELog.info( "Security audit 1 failed at [%s] belonging to player [id=%d]", aCoordinates.toString(), a.getPlayerID() );
AELog.info( "Security audit 2 failed at [%s] belonging to player [id=%d]", bCoordinates.toString(), b.getPlayerID() );
}
throw new SecurityConnectionException();
}
// Create the actual connection
final GridConnection connection = new GridConnection( a, b, fromAtoB );
// Update both nodes with the new connection.
if( a.getMyGrid() == null )
{
b.setGrid( a.getInternalGrid() );
}
else
{
if( a.getMyGrid() == null )
{
final GridPropagator gp = new GridPropagator( b.getInternalGrid() );
aNode.beginVisit( gp );
}
else if( b.getMyGrid() == null )
{
final GridPropagator gp = new GridPropagator( a.getInternalGrid() );
bNode.beginVisit( gp );
}
else if( connection.isNetworkABetter( a, b ) )
{
final GridPropagator gp = new GridPropagator( a.getInternalGrid() );
b.beginVisit( gp );
}
else
{
final GridPropagator gp = new GridPropagator( b.getInternalGrid() );
a.beginVisit( gp );
}
}
// a connection was destroyed RE-PATH!!
final IPathingGrid p = connection.sideA.getInternalGrid().getCache( IPathingGrid.class );
p.repath();
connection.sideA.addConnection( connection );
connection.sideB.addConnection( connection );
return connection;
}
}

View file

@ -33,6 +33,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import appeng.api.exceptions.FailedConnectionException;
import appeng.api.exceptions.SecurityConnectionException;
import appeng.api.networking.GridFlags;
import appeng.api.networking.GridNotification;
import appeng.api.networking.IGrid;
@ -50,6 +51,7 @@ import appeng.api.util.AEColor;
import appeng.api.util.AEPartLocation;
import appeng.api.util.DimensionalCoord;
import appeng.api.util.IReadOnlyCollection;
import appeng.core.AELog;
import appeng.core.worlddata.WorldData;
import appeng.hooks.TickHandler;
import appeng.me.pathfinding.IPathItem;
@ -216,7 +218,7 @@ public class GridNode implements IGridNode, IPathItem
this.compressedData |= ( 1 << ( dir.ordinal() + 8 ) );
}
this.FindConnections();
this.findConnections();
this.getInternalGrid();
}
@ -393,7 +395,7 @@ public class GridNode implements IGridNode, IPathItem
return this.usedChannels;
}
private void FindConnections()
private void findConnections()
{
if( !this.gridProxy.isWorldAccessible() )
{
@ -455,11 +457,18 @@ public class GridNode implements IGridNode, IPathItem
// construct a new connection between these two nodes.
try
{
new GridConnection( node, this, f.getOpposite() );
GridConnection.create( node, this, f.getOpposite() );
}
catch( SecurityConnectionException e )
{
AELog.debug( e );
TickHandler.INSTANCE.addCallable( node.getWorld(), new MachineSecurityBreak( this ) );
return;
}
catch( final FailedConnectionException e )
{
TickHandler.INSTANCE.addCallable( node.getWorld(), new MachineSecurityBreak( this ) );
AELog.debug( e );
return;
}
@ -482,11 +491,19 @@ public class GridNode implements IGridNode, IPathItem
// construct a new connection between these two nodes.
try
{
new GridConnection( node, this, f.getOpposite() );
GridConnection.create( node, this, f.getOpposite() );
}
catch( SecurityConnectionException e )
{
AELog.debug( e );
TickHandler.INSTANCE.addCallable( node.getWorld(), new MachineSecurityBreak( this ) );
return;
}
catch( final FailedConnectionException e )
{
TickHandler.INSTANCE.addCallable( node.getWorld(), new MachineSecurityBreak( this ) );
AELog.debug( e );
return;
}

View file

@ -38,6 +38,7 @@ import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.util.AEPartLocation;
import appeng.api.util.WorldCoord;
import appeng.core.AELog;
import appeng.me.cache.helpers.ConnectionWrapper;
import appeng.me.cluster.IAECluster;
import appeng.tile.qnb.TileQuantumBridge;
@ -161,6 +162,7 @@ public class QuantumCluster implements ILocatable, IAECluster
catch( final FailedConnectionException e )
{
// :(
AELog.debug( e );
}
}
else

View file

@ -241,11 +241,11 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
{
try
{
new GridConnection( cn, sn, AEPartLocation.INTERNAL );
GridConnection.create( cn, sn, AEPartLocation.INTERNAL );
}
catch( final FailedConnectionException e )
{
// ekk!
AELog.debug( e );
bp.removeFromWorld();
this.setCenter( null );
@ -292,11 +292,11 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
{
try
{
new GridConnection( cn, sn, AEPartLocation.INTERNAL );
GridConnection.create( cn, sn, AEPartLocation.INTERNAL );
}
catch( final FailedConnectionException e )
{
// ekk!
AELog.debug( e );
bp.removeFromWorld();
this.setSide( side, null );
@ -637,6 +637,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
catch( final FailedConnectionException e )
{
// ekk
AELog.debug( e );
}
}
}

View file

@ -41,6 +41,7 @@ import appeng.api.parts.IPartHost;
import appeng.api.parts.IPartModel;
import appeng.api.util.AECableType;
import appeng.api.util.AEPartLocation;
import appeng.core.AELog;
import appeng.core.AppEng;
import appeng.helpers.Reflected;
import appeng.items.parts.PartModels;
@ -208,6 +209,7 @@ public class PartToggleBus extends PartBasicState
catch( final FailedConnectionException e )
{
// :(
AELog.debug( e );
}
}
else

View file

@ -247,6 +247,8 @@ public class PartP2PTunnelME extends PartP2PTunnel<PartP2PTunnelME> implements I
{
final TileEntity start = this.getTile();
final TileEntity end = me.getTile();
AELog.debug( e );
AELog.warn( "Failed to establish a ME P2P Tunnel between the tunnels at [x=%d, y=%d, z=%d] and [x=%d, y=%d, z=%d]",
start.getPos().getX(), start.getPos().getY(), start.getPos().getZ(), end.getPos().getX(), end.getPos().getY(),

View file

@ -209,8 +209,7 @@ public class TileController extends AENetworkPowerTile
*/
private boolean checkController( final BlockPos pos )
{
final BlockPos ownPos = this.getPos();
if( this.world.getChunkProvider().getLoadedChunk( ownPos.getX() >> 4, ownPos.getZ() >> 4 ) != null )
if( this.world.getChunkProvider().getLoadedChunk( pos.getX() >> 4, pos.getZ() >> 4 ) != null )
{
return this.world.getTileEntity( pos ) instanceof TileController;
}

View file

@ -1296,11 +1296,11 @@ public class Platform
{
if( a.getLastSecurityKey() == -1 && b.getLastSecurityKey() == -1 )
{
return false;
return true;
}
else if( a.getLastSecurityKey() == b.getLastSecurityKey() )
{
return false;
return true;
}
final boolean a_isSecure = isPowered( a.getGrid() ) && a.getLastSecurityKey() != -1;
@ -1308,15 +1308,17 @@ public class Platform
if( AEConfig.instance().isFeatureEnabled( AEFeature.LOG_SECURITY_AUDITS ) )
{
AELog.info(
"Audit: " + a_isSecure + " : " + b_isSecure + " @ " + a.getLastSecurityKey() + " vs " + b.getLastSecurityKey() + " & " + a
.getPlayerID() + " vs " + b.getPlayerID() );
final String locationA = a.getGridBlock().isWorldAccessible() ? a.getGridBlock().getLocation().toString() : "notInWorld";
final String locationB = b.getGridBlock().isWorldAccessible() ? b.getGridBlock().getLocation().toString() : "notInWorld";
AELog.info( "Audit: Node A [isSecure=%b, key=%d, playerID=%d, location={%s}] vs Node B[isSecure=%b, key=%d, playerID=%d, location={%s}]",
a_isSecure, a.getLastSecurityKey(), a.getPlayerID(), locationA, b_isSecure, b.getLastSecurityKey(), b.getPlayerID(), locationB );
}
// can't do that son...
if( a_isSecure && b_isSecure )
{
return true;
return false;
}
if( !a_isSecure && b_isSecure )
@ -1329,7 +1331,7 @@ public class Platform
return checkPlayerPermissions( a.getGrid(), b.getPlayerID() );
}
return false;
return true;
}
private static boolean isPowered( final IGrid grid )
@ -1347,22 +1349,22 @@ public class Platform
{
if( grid == null )
{
return false;
return true;
}
final ISecurityGrid gs = grid.getCache( ISecurityGrid.class );
if( gs == null )
{
return false;
return true;
}
if( !gs.isAvailable() )
{
return false;
return true;
}
return !gs.hasPermission( playerID, SecurityPermissions.BUILD );
return gs.hasPermission( playerID, SecurityPermissions.BUILD );
}
public static void configurePlayer( final EntityPlayer player, final AEPartLocation side, final TileEntity tile )