From 5e21101619d7cf8c7d2c135659e665e7c7823770 Mon Sep 17 00:00:00 2001 From: PrototypeTrousers Date: Thu, 28 Oct 2021 23:49:16 -0300 Subject: [PATCH] n-to-n p2p network monitor checks nesting by action source --- .../appeng/core/localization/WailaText.java | 6 +- .../modules/theoneprobe/TheOneProbeText.java | 2 + .../part/P2PStateInfoProvider.java | 34 +++++++-- .../waila/part/P2PStateWailaDataProvider.java | 37 ++++++++-- .../java/appeng/me/cache/NetworkMonitor.java | 39 +++++----- src/main/java/appeng/me/cache/P2PCache.java | 73 ++++++++++++++----- .../java/appeng/parts/p2p/PartP2PFluids.java | 31 ++++++-- .../java/appeng/parts/p2p/PartP2PItems.java | 30 ++++++-- .../java/appeng/parts/p2p/PartP2PLight.java | 19 +++-- .../appeng/parts/p2p/PartP2PRedstone.java | 15 +++- .../java/appeng/parts/p2p/PartP2PTunnel.java | 68 +++++++++++------ .../appliedenergistics2/lang/en_us.lang | 10 ++- 12 files changed, 268 insertions(+), 96 deletions(-) diff --git a/src/main/java/appeng/core/localization/WailaText.java b/src/main/java/appeng/core/localization/WailaText.java index c5378abcf..98ac1442e 100644 --- a/src/main/java/appeng/core/localization/WailaText.java +++ b/src/main/java/appeng/core/localization/WailaText.java @@ -31,8 +31,10 @@ public enum WailaText DeviceMissingChannel, P2PUnlinked, - P2PInputOneOutput, - P2PInputManyOutputs, + P2P_INPUT_ONE_OUTPUT, + P2P_INPUT_MANY_OUTPUTS, + P2P_OUTPUT_ONE_INPUT, + P2P_OUTPUT_MANY_INPUTS, P2POutput, Locked, diff --git a/src/main/java/appeng/integration/modules/theoneprobe/TheOneProbeText.java b/src/main/java/appeng/integration/modules/theoneprobe/TheOneProbeText.java index 320c946b1..b5c03e515 100644 --- a/src/main/java/appeng/integration/modules/theoneprobe/TheOneProbeText.java +++ b/src/main/java/appeng/integration/modules/theoneprobe/TheOneProbeText.java @@ -35,6 +35,8 @@ public enum TheOneProbeText P2P_UNLINKED, P2P_INPUT_ONE_OUTPUT, P2P_INPUT_MANY_OUTPUTS, + P2P_OUTPUT_ONE_INPUT, + P2P_OUTPUT_MANY_INPUTS, P2P_OUTPUT, P2P_FREQUENCY, diff --git a/src/main/java/appeng/integration/modules/theoneprobe/part/P2PStateInfoProvider.java b/src/main/java/appeng/integration/modules/theoneprobe/part/P2PStateInfoProvider.java index 985dd05c2..42b6f185f 100644 --- a/src/main/java/appeng/integration/modules/theoneprobe/part/P2PStateInfoProvider.java +++ b/src/main/java/appeng/integration/modules/theoneprobe/part/P2PStateInfoProvider.java @@ -57,11 +57,11 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider // The default state int state = STATE_UNLINKED; - int outputCount = 0; + int outputCount = getOutputCount( tunnel ); + int inputCount = getInputCount( tunnel ); if( !tunnel.isOutput() ) { - outputCount = getOutputCount( tunnel ); if( outputCount > 0 ) { // Only set it to INPUT if we know there are any outputs @@ -70,8 +70,7 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider } else { - final PartP2PTunnel input = tunnel.getInput(); - if( input != null ) + if( inputCount > 0 ) { state = STATE_OUTPUT; } @@ -83,7 +82,7 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider probeInfo.text( TheOneProbeText.P2P_UNLINKED.getLocal() ); break; case STATE_OUTPUT: - probeInfo.text( TheOneProbeText.P2P_OUTPUT.getLocal() ); + probeInfo.text( getInputText( inputCount ) ); break; case STATE_INPUT: probeInfo.text( getOutputText( outputCount ) ); @@ -110,6 +109,19 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider } } + private static int getInputCount( PartP2PTunnel tunnel ) + { + try + { + return Iterators.size( tunnel.getInputs().iterator() ); + } + catch( GridAccessException e ) + { + // Well... unknown size it is! + return 0; + } + } + private static String getOutputText( int outputs ) { if( outputs <= 1 ) @@ -122,4 +134,16 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider } } + private static String getInputText( int inputs ) + { + if( inputs <= 1 ) + { + return TheOneProbeText.P2P_OUTPUT_ONE_INPUT.getLocal(); + } + else + { + return String.format( TheOneProbeText.P2P_OUTPUT_MANY_INPUTS.getLocal(), inputs ); + } + } + } diff --git a/src/main/java/appeng/integration/modules/waila/part/P2PStateWailaDataProvider.java b/src/main/java/appeng/integration/modules/waila/part/P2PStateWailaDataProvider.java index bf6fb98c3..ef000ec32 100644 --- a/src/main/java/appeng/integration/modules/waila/part/P2PStateWailaDataProvider.java +++ b/src/main/java/appeng/integration/modules/waila/part/P2PStateWailaDataProvider.java @@ -21,6 +21,7 @@ package appeng.integration.modules.waila.part; import java.util.List; +import appeng.integration.modules.theoneprobe.TheOneProbeText; import com.google.common.collect.Iterators; import net.minecraft.entity.player.EntityPlayerMP; @@ -117,11 +118,11 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider // The default state int state = STATE_UNLINKED; - int outputCount = 0; + int outputCount = getOutputCount( tunnel ); + int inputCount = getInputCount( tunnel ); if( !tunnel.isOutput() ) { - outputCount = getOutputCount( tunnel ); if( outputCount > 0 ) { // Only set it to INPUT if we know there are any outputs @@ -130,8 +131,7 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider } else { - PartP2PTunnel input = tunnel.getInput(); - if( input != null ) + if( inputCount > 0 ) { state = STATE_OUTPUT; } @@ -160,15 +160,40 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider } } + private static int getInputCount( PartP2PTunnel tunnel ) + { + try + { + return Iterators.size( tunnel.getInputs().iterator() ); + } + catch( GridAccessException e ) + { + // Well... unknown size it is! + return 0; + } + } + private static String getOutputText( int outputs ) { if( outputs <= 1 ) { - return WailaText.P2PInputOneOutput.getLocal(); + return WailaText.P2P_INPUT_ONE_OUTPUT.getLocal(); } else { - return String.format( WailaText.P2PInputManyOutputs.getLocal(), outputs ); + return String.format( WailaText.P2P_INPUT_MANY_OUTPUTS.getLocal(), outputs ); + } + } + + private static String getInputText( int inputs ) + { + if( inputs <= 1 ) + { + return WailaText.P2P_OUTPUT_ONE_INPUT.getLocal(); + } + else + { + return String.format( WailaText.P2P_OUTPUT_MANY_INPUTS.getLocal(), inputs ); } } diff --git a/src/main/java/appeng/me/cache/NetworkMonitor.java b/src/main/java/appeng/me/cache/NetworkMonitor.java index 733b128ad..f4f8c1ac8 100644 --- a/src/main/java/appeng/me/cache/NetworkMonitor.java +++ b/src/main/java/appeng/me/cache/NetworkMonitor.java @@ -47,8 +47,8 @@ import java.util.Map.Entry; public class NetworkMonitor> implements IMEMonitor { @Nonnull - private static final Deque> GLOBAL_DEPTH = Queues.newArrayDeque(); - private static final Set> MONITORS = new HashSet<>(); + private static final Set> NESTED_MONITORS = new HashSet<>(); + private static final HashMap>> sourceSetHashMap = new HashMap<>(); protected static boolean nested = false; protected boolean isNested = false; @@ -137,17 +137,16 @@ public class NetworkMonitor> implements IMEMonitor return 0; } - public long incGridCurrentCount(long count) + public void incGridCurrentCount( long count ) { if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) { - return gridItemCount += count; + gridItemCount += count; } else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) { - return gridFluidCount += count; + gridFluidCount += count; } - return 0; } @Nonnull @@ -230,15 +229,16 @@ public class NetworkMonitor> implements IMEMonitor protected void postChange( final boolean add, final Iterable changes, final IActionSource src ) { - if( MONITORS.contains( this ) ) + + if( sourceSetHashMap.get( src ) != null && sourceSetHashMap.get( src ).contains( this ) ) { + NESTED_MONITORS.add( this ); nested = true; return; } - MONITORS.add( this ); - - GLOBAL_DEPTH.push( this ); + sourceSetHashMap.putIfAbsent( src, new HashSet<>() ); + sourceSetHashMap.get( src ).add( this ); this.sendEvent = true; @@ -282,21 +282,20 @@ public class NetworkMonitor> implements IMEMonitor this.notifyListenersOfChange( changes, src ); - final NetworkMonitor last = GLOBAL_DEPTH.pop(); - - if( GLOBAL_DEPTH.isEmpty() ) + sourceSetHashMap.get( src ).remove( this ); + if( sourceSetHashMap.get( src ).isEmpty() ) { - for( NetworkMonitor nm : MONITORS ) + sourceSetHashMap.remove( src ); + } + + if( sourceSetHashMap.isEmpty() ) + { + for( NetworkMonitor nm : NESTED_MONITORS ) { nm.setupForceUpdate(); } nested = false; - MONITORS.clear(); - } - - if( last != this ) - { - throw new IllegalStateException( "Invalid Access to Networked Storage API detected." ); + NESTED_MONITORS.clear(); } } diff --git a/src/main/java/appeng/me/cache/P2PCache.java b/src/main/java/appeng/me/cache/P2PCache.java index f25bbb080..21b450d2a 100644 --- a/src/main/java/appeng/me/cache/P2PCache.java +++ b/src/main/java/appeng/me/cache/P2PCache.java @@ -19,7 +19,7 @@ package appeng.me.cache; -import java.util.HashMap; +import java.util.Collection; import java.util.Random; import com.google.common.collect.LinkedHashMultimap; @@ -46,7 +46,7 @@ public class P2PCache implements IGridCache private static final TunnelCollection NULL_COLLECTION = new TunnelCollection( null, null ); private final IGrid myGrid; - private final HashMap inputs = new HashMap<>(); + private final Multimap inputs = LinkedHashMultimap.create(); private final Multimap outputs = LinkedHashMultimap.create(); private final Random frequencyGenerator; @@ -110,10 +110,19 @@ public class P2PCache implements IGridCache } else { - this.inputs.remove( t.getFrequency() ); + this.inputs.remove( t.getFrequency(), t ); } - this.updateTunnel( t.getFrequency(), !t.isOutput(), false ); + if( this.inputs.get( t.getFrequency() ).isEmpty() ) + { + this.inputs.removeAll( t.getFrequency() ); + } + if( this.outputs.get( t.getFrequency() ).isEmpty() ) + { + this.outputs.removeAll( t.getFrequency() ); + } + + this.updateTunnel( t.getFrequency(), t.isOutput(), false ); } } @@ -142,7 +151,7 @@ public class P2PCache implements IGridCache this.inputs.put( t.getFrequency(), t ); } - this.updateTunnel( t.getFrequency(), !t.isOutput(), false ); + this.updateTunnel( t.getFrequency(), t.isOutput(), false ); } } @@ -164,6 +173,20 @@ public class P2PCache implements IGridCache } + public void removeTunnel( final PartP2PTunnel t, short freq ) + { + this.outputs.remove( freq, t ); + this.inputs.remove( freq, t ); + if( this.inputs.get( t.getFrequency() ).isEmpty() ) + { + this.inputs.removeAll( t.getFrequency() ); + } + if( this.outputs.get( t.getFrequency() ).isEmpty() ) + { + this.outputs.removeAll( t.getFrequency() ); + } + } + private void updateTunnel( final short freq, final boolean updateOutputs, final boolean configChange ) { for( final PartP2PTunnel p : this.outputs.get( freq ) ) @@ -175,8 +198,7 @@ public class P2PCache implements IGridCache p.onTunnelNetworkChange(); } - final PartP2PTunnel in = this.inputs.get( freq ); - if( in != null ) + for( final PartP2PTunnel in : this.inputs.get( freq ) ) { if( configChange ) { @@ -195,7 +217,7 @@ public class P2PCache implements IGridCache if( this.inputs.containsValue( t ) ) { - this.inputs.remove( t.getFrequency() ); + this.inputs.remove( t.getFrequency(), t ); } t.setFrequency( newFrequency ); @@ -211,7 +233,6 @@ public class P2PCache implements IGridCache // AELog.info( "update-" + (t.output ? "output: " : "input: ") + t.freq ); this.updateTunnel( t.getFrequency(), t.isOutput(), true ); - this.updateTunnel( t.getFrequency(), !t.isOutput(), true ); } public short newFrequency() @@ -236,25 +257,43 @@ public class P2PCache implements IGridCache public TunnelCollection getOutputs( final short freq, final Class c ) { - final PartP2PTunnel in = this.inputs.get( freq ); + Collection in = this.inputs.get( freq ); if( in == null ) { return NULL_COLLECTION; } - final TunnelCollection out = this.inputs.get( freq ).getCollection( this.outputs.get( freq ), c ); + TunnelCollection out; + for( PartP2PTunnel part : this.inputs.get( freq ) ) + { + out = part.getCollection( this.outputs.get( freq ), c ); + if( out != null ) + { + return out; + } + } + return NULL_COLLECTION; + } + + public TunnelCollection getInputs( final short freq, final Class c ) + { + Collection out = this.outputs.get( freq ); if( out == null ) { return NULL_COLLECTION; } - return out; - } - - public PartP2PTunnel getInput( final short freq ) - { - return this.inputs.get( freq ); + TunnelCollection in; + for( PartP2PTunnel part : this.outputs.get( freq ) ) + { + in = part.getCollection( this.inputs.get( freq ), c ); + if( in != null ) + { + return in; + } + } + return NULL_COLLECTION; } } diff --git a/src/main/java/appeng/parts/p2p/PartP2PFluids.java b/src/main/java/appeng/parts/p2p/PartP2PFluids.java index 0590ef63b..3c840559d 100644 --- a/src/main/java/appeng/parts/p2p/PartP2PFluids.java +++ b/src/main/java/appeng/parts/p2p/PartP2PFluids.java @@ -83,10 +83,19 @@ public class PartP2PFluids extends PartP2PTunnel implements IFlui if( this.isOutput() ) { - final PartP2PFluids in = this.getInput(); - if( in != null ) + try { - in.onTunnelNetworkChange(); + for( PartP2PFluids in : this.getInputs() ) + { + if( in != null ) + { + in.onTunnelNetworkChange(); + } + } + } + catch( GridAccessException e ) + { + e.printStackTrace(); } } } @@ -124,13 +133,21 @@ public class PartP2PFluids extends PartP2PTunnel implements IFlui { if( !this.isOutput() ) { - final PartP2PFluids tun = this.getInput(); - if( tun != null ) + try { - return ACTIVE_TANK; + for( PartP2PFluids tun : this.getInputs() ) + { + if( tun != null ) + { + return ACTIVE_TANK; + } + } + } + catch( GridAccessException e ) + { + e.printStackTrace(); } } - return INACTIVE_TANK; } diff --git a/src/main/java/appeng/parts/p2p/PartP2PItems.java b/src/main/java/appeng/parts/p2p/PartP2PItems.java index 61deecd4f..0db703872 100644 --- a/src/main/java/appeng/parts/p2p/PartP2PItems.java +++ b/src/main/java/appeng/parts/p2p/PartP2PItems.java @@ -74,10 +74,19 @@ public class PartP2PItems extends PartP2PTunnel implements IItemHa public void onNeighborChanged( IBlockAccess w, BlockPos pos, BlockPos neighbor ) { this.cachedInv = null; - final PartP2PItems input = this.getInput(); - if( input != null && this.isOutput() ) + try { - input.onTunnelNetworkChange(); + for( PartP2PItems input : this.getInputs() ) + { + if( input != null && this.isOutput() ) + { + input.onTunnelNetworkChange(); + } + } + } + catch( GridAccessException e ) + { + e.printStackTrace(); } } @@ -222,10 +231,19 @@ public class PartP2PItems extends PartP2PTunnel implements IItemHa } else { - final PartP2PItems input = this.getInput(); - if( input != null ) + try { - input.getHost().notifyNeighbors(); + for( PartP2PItems input : this.getInputs() ) + { + if( input != null ) + { + input.getHost().notifyNeighbors(); + } + } + } + catch( GridAccessException e ) + { + e.printStackTrace(); } } } diff --git a/src/main/java/appeng/parts/p2p/PartP2PLight.java b/src/main/java/appeng/parts/p2p/PartP2PLight.java index 3211d865c..20167003b 100644 --- a/src/main/java/appeng/parts/p2p/PartP2PLight.java +++ b/src/main/java/appeng/parts/p2p/PartP2PLight.java @@ -196,14 +196,23 @@ public class PartP2PLight extends PartP2PTunnel implements IGridTi { if( this.isOutput() ) { - final PartP2PLight src = this.getInput(); - if( src != null && src.getProxy().isActive() ) + try { - this.setLightLevel( src.lastValue ); + for( PartP2PLight src : this.getInputs() ) + { + if( src != null && src.getProxy().isActive() ) + { + this.setLightLevel( src.lastValue ); + } + else + { + this.getHost().markForUpdate(); + } + } } - else + catch( GridAccessException e ) { - this.getHost().markForUpdate(); + e.printStackTrace(); } } else diff --git a/src/main/java/appeng/parts/p2p/PartP2PRedstone.java b/src/main/java/appeng/parts/p2p/PartP2PRedstone.java index 13c85d8e8..df75b8299 100644 --- a/src/main/java/appeng/parts/p2p/PartP2PRedstone.java +++ b/src/main/java/appeng/parts/p2p/PartP2PRedstone.java @@ -70,10 +70,19 @@ public class PartP2PRedstone extends PartP2PTunnel { if( this.isOutput() ) { - final PartP2PRedstone in = this.getInput(); - if( in != null ) + try { - this.putInput( in.power ); + for( PartP2PRedstone in : this.getInputs() ) + { + if( in != null ) + { + this.putInput( in.power ); + } + } + } + catch( GridAccessException e ) + { + e.printStackTrace(); } } } diff --git a/src/main/java/appeng/parts/p2p/PartP2PTunnel.java b/src/main/java/appeng/parts/p2p/PartP2PTunnel.java index 4d30c45c5..413fbf276 100644 --- a/src/main/java/appeng/parts/p2p/PartP2PTunnel.java +++ b/src/main/java/appeng/parts/p2p/PartP2PTunnel.java @@ -53,6 +53,7 @@ import appeng.me.cache.P2PCache; import appeng.me.cache.helpers.TunnelCollection; import appeng.parts.PartBasicState; import appeng.util.Platform; +import org.lwjgl.input.Keyboard; public abstract class PartP2PTunnel extends PartBasicState @@ -77,26 +78,13 @@ public abstract class PartP2PTunnel extends PartBasicSt return null; } - public T getInput() + public TunnelCollection getInputs() throws GridAccessException { - if( this.getFrequency() == 0 ) + if( this.getProxy().isActive() && this.getFrequency() != 0 ) { - return null; + return (TunnelCollection) this.getProxy().getP2P().getInputs( this.getFrequency(), this.getClass() ); } - - try - { - final PartP2PTunnel tunnel = this.getProxy().getP2P().getInput( this.getFrequency() ); - if( this.getClass().isInstance( tunnel ) ) - { - return (T) tunnel; - } - } - catch( final GridAccessException e ) - { - // :P - } - return null; + return new TunnelCollection( new ArrayList(), this.getClass() ); } public TunnelCollection getOutputs() throws GridAccessException @@ -211,14 +199,28 @@ public abstract class PartP2PTunnel extends PartBasicSt final IPart testPart = ( (IPartItem) newType.getItem() ).createPartFromItemStack( newType ); if( testPart instanceof PartP2PTunnel ) { + + try + { + this.getProxy().getP2P().removeTunnel( this, this.getFrequency() ); + } + catch( GridAccessException e ) + { + e.printStackTrace(); + } + this.getHost().removePart( this.getSide(), true ); + final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand ); final IPart newBus = this.getHost().getPart( dir ); if( newBus instanceof PartP2PTunnel ) { final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus; - newTunnel.setOutput( true ); + if( !Keyboard.isKeyDown( Keyboard.KEY_LCONTROL ) && !Keyboard.isKeyDown( Keyboard.KEY_RCONTROL ) ) + { + newTunnel.setOutput( true ); + } try { @@ -295,7 +297,17 @@ public abstract class PartP2PTunnel extends PartBasicSt final boolean oldOutput = this.isOutput(); final short myFreq = this.getFrequency(); + try + { + this.getProxy().getP2P().removeTunnel( this, this.getFrequency() ); + } + catch( GridAccessException e ) + { + e.printStackTrace(); + } + this.getHost().removePart( this.getSide(), false ); + final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand ); final IPart newBus = this.getHost().getPart( dir ); @@ -303,7 +315,6 @@ public abstract class PartP2PTunnel extends PartBasicSt { final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus; newTunnel.setOutput( oldOutput ); - newTunnel.onTunnelNetworkChange(); try { @@ -314,9 +325,10 @@ public abstract class PartP2PTunnel extends PartBasicSt { // :P } + newTunnel.onTunnelNetworkChange(); + } - Platform.notifyBlocksOfNeighbors( this.getTile().getWorld(), this.getTile().getPos() ); return true; } } @@ -353,7 +365,17 @@ public abstract class PartP2PTunnel extends PartBasicSt final ItemStack newType = this.getHost().getPart( this.getSide() ).getItemStack( PartItemStack.WRENCH ); + try + { + this.getProxy().getP2P().removeTunnel( this, this.getFrequency() ); + } + catch( GridAccessException e ) + { + e.printStackTrace(); + } + this.getHost().removePart( this.getSide(), false ); + final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand ); final IPart newBus = this.getHost().getPart( dir ); @@ -361,14 +383,17 @@ public abstract class PartP2PTunnel extends PartBasicSt { final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus; newTunnel.setOutput( false ); - newTunnel.onTunnelNetworkChange(); newTunnel.getProxy().getP2P().updateFreq( newTunnel, newFreq ); + + newTunnel.onTunnelNetworkChange(); } } else { this.getProxy().getP2P().updateFreq( this, newFreq ); + this.onTunnelNetworkChange(); } + Platform.notifyBlocksOfNeighbors( this.getTile().getWorld(), this.getTile().getPos() ); } catch( final GridAccessException e ) { @@ -418,7 +443,6 @@ public abstract class PartP2PTunnel extends PartBasicSt public void onTunnelNetworkChange() { - } protected void queueTunnelDrain( final PowerUnits unit, final double f ) diff --git a/src/main/resources/assets/appliedenergistics2/lang/en_us.lang b/src/main/resources/assets/appliedenergistics2/lang/en_us.lang index 9cfe44d0b..6332b1eaa 100644 --- a/src/main/resources/assets/appliedenergistics2/lang/en_us.lang +++ b/src/main/resources/assets/appliedenergistics2/lang/en_us.lang @@ -405,8 +405,10 @@ waila.appliedenergistics2.Showing=Showing waila.appliedenergistics2.Contains=Contains waila.appliedenergistics2.Channels=%1$d of %2$d Channels waila.appliedenergistics2.P2PUnlinked=Unlinked -waila.appliedenergistics2.P2PInputOneOutput=Linked (Input Side) -waila.appliedenergistics2.P2PInputManyOutputs=Linked (Input Side) - %d Outputs +waila.appliedenergistics2.p2p_input_one_output=Linked (Input Side) - 1 Output +waila.appliedenergistics2.p2p_input_many_outputs=Linked (Input Side) - %d Outputs +waila.appliedenergistics2.p2p_output_one_input=Linked (Output Side) - 1 Input +waila.appliedenergistics2.p2p_output_many_inputs=Linked (Output Side) - %d Inputs waila.appliedenergistics2.P2POutput=Linked (Output Side) // TheOneProbe @@ -420,8 +422,10 @@ theoneprobe.appliedenergistics2.showing=Showing theoneprobe.appliedenergistics2.contains=Contains theoneprobe.appliedenergistics2.channels=%1$d of %2$d Channels theoneprobe.appliedenergistics2.p2p_unlinked=Unlinked -theoneprobe.appliedenergistics2.p2p_input_one_output=Linked (Input Side) +theoneprobe.appliedenergistics2.p2p_input_one_output=Linked (Input Side) - 1 Output theoneprobe.appliedenergistics2.p2p_input_many_outputs=Linked (Input Side) - %d Outputs +theoneprobe.appliedenergistics2.p2p_output_one_input=Linked (Output Side) - 1 Input +theoneprobe.appliedenergistics2.p2p_output_many_inputs=Linked (Output Side) - %d Inputs theoneprobe.appliedenergistics2.p2p_output=Linked (Output Side) theoneprobe.appliedenergistics2.p2p_frequency=Frequency: %1$s theoneprobe.appliedenergistics2.stored_energy=%1$d / %2$d