mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-12 19:20:29 +00:00
Convert TileCable to use the wired network API
There are several important things to note here: - The network element is associated with the cable, whilst the peripheral (and so packet sender/receiver) is associated with the modem. This allows us to have the main element be in the centre of the cable block, whilst the modem is in the centre of the adjacent computer. - Cables will connect to any adjacent network element, not just other cables. - Rednet messages are now sent on the computer thread, rather than the cable tick.
This commit is contained in:
parent
74f5093d2a
commit
5c7828dd79
@ -54,8 +54,6 @@ public class RenderOverlayCable
|
||||
GlStateManager.depthMask( false );
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
EnumFacing direction = type != PeripheralType.Cable ? cable.getDirection() : null;
|
||||
|
||||
{
|
||||
EntityPlayer player = event.getPlayer();
|
||||
double x = player.lastTickPosX + (player.posX - player.lastTickPosX) * event.getPartialTicks();
|
||||
@ -78,7 +76,7 @@ public class RenderOverlayCable
|
||||
|
||||
for( EnumFacing facing : EnumFacing.VALUES )
|
||||
{
|
||||
if( direction == facing || BlockCable.isCable( world, pos.offset( facing ) ) )
|
||||
if( BlockCable.doesConnectVisually( state, world, pos, facing ) )
|
||||
{
|
||||
flags |= 1 << facing.ordinal();
|
||||
|
||||
|
@ -11,7 +11,6 @@ import dan200.computercraft.shared.common.TileGeneric;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import dan200.computercraft.shared.peripheral.modem.TileCable;
|
||||
import dan200.computercraft.shared.util.WorldUtil;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.properties.PropertyBool;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.state.BlockFaceShape;
|
||||
@ -51,23 +50,6 @@ public class BlockCable extends BlockPeripheralBase
|
||||
public static final PropertyBool DOWN = PropertyBool.create( "down" );
|
||||
}
|
||||
|
||||
public static boolean isCable( IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
Block block = world.getBlockState( pos ).getBlock();
|
||||
if( block == ComputerCraft.Blocks.cable )
|
||||
{
|
||||
switch( ComputerCraft.Blocks.cable.getPeripheralType( world, pos ) )
|
||||
{
|
||||
case Cable:
|
||||
case WiredModemWithCable:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Members
|
||||
|
||||
public BlockCable()
|
||||
@ -175,20 +157,17 @@ public class BlockCable extends BlockPeripheralBase
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doesConnect( IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing dir )
|
||||
public static boolean canConnectIn( IBlockState state, EnumFacing direction )
|
||||
{
|
||||
if( state.getValue( Properties.CABLE ) == BlockCableCableVariant.NONE )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if( state.getValue( Properties.MODEM ).getFacing() == dir )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return isCable( world, pos.offset( dir ) );
|
||||
}
|
||||
return state.getValue( BlockCable.Properties.CABLE ) != BlockCableCableVariant.NONE
|
||||
&& state.getValue( BlockCable.Properties.MODEM ).getFacing() != direction;
|
||||
}
|
||||
|
||||
public static boolean doesConnectVisually( IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing direction )
|
||||
{
|
||||
if( state.getValue( Properties.CABLE ) == BlockCableCableVariant.NONE ) return false;
|
||||
if( state.getValue( Properties.MODEM ).getFacing() == direction ) return true;
|
||||
return ComputerCraft.getWiredElementAt( world, pos.offset( direction ), direction.getOpposite() ) != null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -196,12 +175,12 @@ public class BlockCable extends BlockPeripheralBase
|
||||
@Deprecated
|
||||
public IBlockState getActualState( @Nonnull IBlockState state, IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
state = state.withProperty( Properties.NORTH, doesConnect( state, world, pos, EnumFacing.NORTH ) );
|
||||
state = state.withProperty( Properties.SOUTH, doesConnect( state, world, pos, EnumFacing.SOUTH ) );
|
||||
state = state.withProperty( Properties.EAST, doesConnect( state, world, pos, EnumFacing.EAST ) );
|
||||
state = state.withProperty( Properties.WEST, doesConnect( state, world, pos, EnumFacing.WEST ) );
|
||||
state = state.withProperty( Properties.UP, doesConnect( state, world, pos, EnumFacing.UP ) );
|
||||
state = state.withProperty( Properties.DOWN, doesConnect( state, world, pos, EnumFacing.DOWN ) );
|
||||
state = state.withProperty( Properties.NORTH, doesConnectVisually( state, world, pos, EnumFacing.NORTH ) );
|
||||
state = state.withProperty( Properties.SOUTH, doesConnectVisually( state, world, pos, EnumFacing.SOUTH ) );
|
||||
state = state.withProperty( Properties.EAST, doesConnectVisually( state, world, pos, EnumFacing.EAST ) );
|
||||
state = state.withProperty( Properties.WEST, doesConnectVisually( state, world, pos, EnumFacing.WEST ) );
|
||||
state = state.withProperty( Properties.UP, doesConnectVisually( state, world, pos, EnumFacing.UP ) );
|
||||
state = state.withProperty( Properties.DOWN, doesConnectVisually( state, world, pos, EnumFacing.DOWN ) );
|
||||
|
||||
if( state.getValue( Properties.CABLE ) != BlockCableCableVariant.NONE )
|
||||
{
|
||||
@ -345,7 +324,6 @@ public class BlockCable extends BlockPeripheralBase
|
||||
if( WorldUtil.isVecInsideInclusive( bb, hit.hitVec.subtract( pos.getX(), pos.getY(), pos.getZ() ) ) )
|
||||
{
|
||||
world.setBlockState( pos, state.withProperty( Properties.MODEM, BlockCableModemVariant.None ), 3 );
|
||||
cable.modemChanged();
|
||||
item = PeripheralItemFactory.create( PeripheralType.WiredModem, null, 1 );
|
||||
}
|
||||
else
|
||||
@ -365,6 +343,7 @@ public class BlockCable extends BlockPeripheralBase
|
||||
return super.removedByPlayer( state, world, pos, player, willHarvest );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack getPickBlock( @Nonnull IBlockState state, RayTraceResult hit, @Nonnull World world, @Nonnull BlockPos pos, EntityPlayer player )
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,59 @@
|
||||
package dan200.computercraft.shared.peripheral.modem;
|
||||
|
||||
import dan200.computercraft.api.network.wired.IWiredNetworkChange;
|
||||
import dan200.computercraft.api.network.wired.IWiredElement;
|
||||
import dan200.computercraft.api.network.wired.IWiredNode;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.wired.WiredNode;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class WiredModemElement implements IWiredElement
|
||||
{
|
||||
private final IWiredNode node = new WiredNode( this );
|
||||
private final Map<String, IPeripheral> remotePeripherals = new HashMap<>();
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IWiredNode getNode()
|
||||
{
|
||||
return node;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getSenderID()
|
||||
{
|
||||
return "modem";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void networkChanged( @Nonnull IWiredNetworkChange change )
|
||||
{
|
||||
synchronized( remotePeripherals )
|
||||
{
|
||||
remotePeripherals.keySet().removeAll( change.peripheralsRemoved().keySet() );
|
||||
for( String name : change.peripheralsRemoved().keySet() )
|
||||
{
|
||||
detachPeripheral( name );
|
||||
}
|
||||
|
||||
for( Map.Entry<String, IPeripheral> peripheral : change.peripheralsAdded().entrySet() )
|
||||
{
|
||||
attachPeripheral( peripheral.getKey(), peripheral.getValue() );
|
||||
}
|
||||
remotePeripherals.putAll( change.peripheralsAdded() );
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, IPeripheral> getRemotePeripherals()
|
||||
{
|
||||
return remotePeripherals;
|
||||
}
|
||||
|
||||
protected abstract void attachPeripheral( String name, IPeripheral peripheral );
|
||||
|
||||
protected abstract void detachPeripheral( String name );
|
||||
}
|
@ -0,0 +1,410 @@
|
||||
package dan200.computercraft.shared.peripheral.modem;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import dan200.computercraft.api.filesystem.IMount;
|
||||
import dan200.computercraft.api.filesystem.IWritableMount;
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.network.IPacketNetwork;
|
||||
import dan200.computercraft.api.network.wired.IWiredNode;
|
||||
import dan200.computercraft.api.network.wired.IWiredSender;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
|
||||
|
||||
public class WiredModemPeripheral extends ModemPeripheral implements IWiredSender
|
||||
{
|
||||
private final WiredModemElement modem;
|
||||
|
||||
private final Map<String, RemotePeripheralWrapper> peripheralWrappers = new HashMap<>();
|
||||
|
||||
public WiredModemPeripheral( WiredModemElement modem )
|
||||
{
|
||||
this.modem = modem;
|
||||
}
|
||||
|
||||
//region IPacketSender implementation
|
||||
@Override
|
||||
public boolean isInterdimensional()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRange()
|
||||
{
|
||||
return 256.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IPacketNetwork getNetwork()
|
||||
{
|
||||
return modem.getNode();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public World getWorld()
|
||||
{
|
||||
return modem.getWorld();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Vec3d getPosition()
|
||||
{
|
||||
return modem.getPosition();
|
||||
}
|
||||
//endregion
|
||||
|
||||
//region IPeripheral
|
||||
@Nonnull
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
String[] methods = super.getMethodNames();
|
||||
String[] newMethods = new String[methods.length + 5];
|
||||
System.arraycopy( methods, 0, newMethods, 0, methods.length );
|
||||
newMethods[methods.length] = "getNamesRemote";
|
||||
newMethods[methods.length + 1] = "isPresentRemote";
|
||||
newMethods[methods.length + 2] = "getTypeRemote";
|
||||
newMethods[methods.length + 3] = "getMethodsRemote";
|
||||
newMethods[methods.length + 4] = "callRemote";
|
||||
return newMethods;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException
|
||||
{
|
||||
String[] methods = super.getMethodNames();
|
||||
switch( method - methods.length )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// getNamesRemote
|
||||
synchronized( peripheralWrappers )
|
||||
{
|
||||
int idx = 1;
|
||||
Map<Object, Object> table = new HashMap<>();
|
||||
for( String name : peripheralWrappers.keySet() )
|
||||
{
|
||||
table.put( idx++, name );
|
||||
}
|
||||
return new Object[]{ table };
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// isPresentRemote
|
||||
String type = getTypeRemote( getString( arguments, 0 ) );
|
||||
return new Object[]{ type != null };
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// getTypeRemote
|
||||
String type = getTypeRemote( getString( arguments, 0 ) );
|
||||
if( type != null )
|
||||
{
|
||||
return new Object[]{ type };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// getMethodsRemote
|
||||
String[] methodNames = getMethodNamesRemote( getString( arguments, 0 ) );
|
||||
if( methodNames != null )
|
||||
{
|
||||
Map<Object, Object> table = new HashMap<>();
|
||||
for( int i = 0; i < methodNames.length; ++i )
|
||||
{
|
||||
table.put( i + 1, methodNames[i] );
|
||||
}
|
||||
return new Object[]{ table };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
// callRemote
|
||||
String remoteName = getString( arguments, 0 );
|
||||
String methodName = getString( arguments, 1 );
|
||||
Object[] methodArgs = new Object[arguments.length - 2];
|
||||
System.arraycopy( arguments, 2, methodArgs, 0, arguments.length - 2 );
|
||||
return callMethodRemote( remoteName, context, methodName, methodArgs );
|
||||
}
|
||||
default:
|
||||
{
|
||||
// The regular modem methods
|
||||
return super.callMethod( computer, context, method, arguments );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attach( @Nonnull IComputerAccess computer )
|
||||
{
|
||||
super.attach( computer );
|
||||
synchronized( modem.getRemotePeripherals() )
|
||||
{
|
||||
synchronized( peripheralWrappers )
|
||||
{
|
||||
for( Map.Entry<String, IPeripheral> entry : modem.getRemotePeripherals().entrySet() )
|
||||
{
|
||||
attachPeripheralImpl( entry.getKey(), entry.getValue() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void detach( @Nonnull IComputerAccess computer )
|
||||
{
|
||||
synchronized( peripheralWrappers )
|
||||
{
|
||||
for( RemotePeripheralWrapper wrapper : peripheralWrappers.values() )
|
||||
{
|
||||
wrapper.detach();
|
||||
}
|
||||
peripheralWrappers.clear();
|
||||
}
|
||||
super.detach( computer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( IPeripheral other )
|
||||
{
|
||||
if( other instanceof WiredModemPeripheral )
|
||||
{
|
||||
WiredModemPeripheral otherModem = (WiredModemPeripheral) other;
|
||||
return otherModem.modem == modem;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//endregion
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IWiredNode getNode()
|
||||
{
|
||||
return modem.getNode();
|
||||
}
|
||||
|
||||
public void attachPeripheral( String name, IPeripheral peripheral )
|
||||
{
|
||||
if( getComputer() == null ) return;
|
||||
|
||||
synchronized( peripheralWrappers )
|
||||
{
|
||||
attachPeripheralImpl( name, peripheral );
|
||||
}
|
||||
}
|
||||
|
||||
public void detachPeripheral( String name )
|
||||
{
|
||||
synchronized( peripheralWrappers )
|
||||
{
|
||||
RemotePeripheralWrapper wrapper = peripheralWrappers.get( name );
|
||||
if( wrapper != null )
|
||||
{
|
||||
peripheralWrappers.remove( name );
|
||||
wrapper.detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void attachPeripheralImpl( String periphName, IPeripheral peripheral )
|
||||
{
|
||||
if( !peripheralWrappers.containsKey( periphName ) )
|
||||
{
|
||||
RemotePeripheralWrapper wrapper = new RemotePeripheralWrapper( modem, peripheral, getComputer(), periphName );
|
||||
peripheralWrappers.put( periphName, wrapper );
|
||||
wrapper.attach();
|
||||
}
|
||||
}
|
||||
|
||||
private String getTypeRemote( String remoteName )
|
||||
{
|
||||
synchronized( peripheralWrappers )
|
||||
{
|
||||
RemotePeripheralWrapper wrapper = peripheralWrappers.get( remoteName );
|
||||
if( wrapper != null )
|
||||
{
|
||||
return wrapper.getType();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String[] getMethodNamesRemote( String remoteName )
|
||||
{
|
||||
synchronized( peripheralWrappers )
|
||||
{
|
||||
RemotePeripheralWrapper wrapper = peripheralWrappers.get( remoteName );
|
||||
if( wrapper != null )
|
||||
{
|
||||
return wrapper.getMethodNames();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object[] callMethodRemote( String remoteName, ILuaContext context, String method, Object[] arguments ) throws LuaException, InterruptedException
|
||||
{
|
||||
RemotePeripheralWrapper wrapper;
|
||||
synchronized( peripheralWrappers )
|
||||
{
|
||||
wrapper = peripheralWrappers.get( remoteName );
|
||||
}
|
||||
if( wrapper != null )
|
||||
{
|
||||
return wrapper.callMethod( context, method, arguments );
|
||||
}
|
||||
throw new LuaException( "No peripheral: " + remoteName );
|
||||
}
|
||||
|
||||
private static class RemotePeripheralWrapper implements IComputerAccess
|
||||
{
|
||||
private final WiredModemElement m_element;
|
||||
private final IPeripheral m_peripheral;
|
||||
private final IComputerAccess m_computer;
|
||||
private final String m_name;
|
||||
|
||||
private final String m_type;
|
||||
private final String[] m_methods;
|
||||
private final Map<String, Integer> m_methodMap;
|
||||
|
||||
public RemotePeripheralWrapper( WiredModemElement element, IPeripheral peripheral, IComputerAccess computer, String name )
|
||||
{
|
||||
m_element = element;
|
||||
m_peripheral = peripheral;
|
||||
m_computer = computer;
|
||||
m_name = name;
|
||||
|
||||
m_type = peripheral.getType();
|
||||
m_methods = peripheral.getMethodNames();
|
||||
assert (m_type != null);
|
||||
assert (m_methods != null);
|
||||
|
||||
m_methodMap = new HashMap<>();
|
||||
for( int i = 0; i < m_methods.length; ++i )
|
||||
{
|
||||
if( m_methods[i] != null )
|
||||
{
|
||||
m_methodMap.put( m_methods[i], i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void attach()
|
||||
{
|
||||
m_peripheral.attach( this );
|
||||
m_computer.queueEvent( "peripheral", new Object[]{ getAttachmentName() } );
|
||||
}
|
||||
|
||||
public void detach()
|
||||
{
|
||||
m_peripheral.detach( this );
|
||||
m_computer.queueEvent( "peripheral_detach", new Object[]{ getAttachmentName() } );
|
||||
}
|
||||
|
||||
public String getType()
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return m_methods;
|
||||
}
|
||||
|
||||
public Object[] callMethod( ILuaContext context, String methodName, Object[] arguments ) throws LuaException, InterruptedException
|
||||
{
|
||||
if( m_methodMap.containsKey( methodName ) )
|
||||
{
|
||||
int method = m_methodMap.get( methodName );
|
||||
return m_peripheral.callMethod( this, context, method, arguments );
|
||||
}
|
||||
throw new LuaException( "No such method " + methodName );
|
||||
}
|
||||
|
||||
// IComputerAccess implementation
|
||||
|
||||
@Override
|
||||
public String mount( @Nonnull String desiredLocation, @Nonnull IMount mount )
|
||||
{
|
||||
return m_computer.mount( desiredLocation, mount, m_name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mount( @Nonnull String desiredLocation, @Nonnull IMount mount, @Nonnull String driveName )
|
||||
{
|
||||
return m_computer.mount( desiredLocation, mount, driveName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mountWritable( @Nonnull String desiredLocation, @Nonnull IWritableMount mount )
|
||||
{
|
||||
return m_computer.mountWritable( desiredLocation, mount, m_name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mountWritable( @Nonnull String desiredLocation, @Nonnull IWritableMount mount, @Nonnull String driveName )
|
||||
{
|
||||
return m_computer.mountWritable( desiredLocation, mount, driveName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unmount( String location )
|
||||
{
|
||||
m_computer.unmount( location );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getID()
|
||||
{
|
||||
return m_computer.getID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queueEvent( @Nonnull String event, Object[] arguments )
|
||||
{
|
||||
m_computer.queueEvent( event, arguments );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getAttachmentName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Map<String, IPeripheral> getAvailablePeripherals()
|
||||
{
|
||||
synchronized( m_element.getRemotePeripherals() )
|
||||
{
|
||||
return ImmutableMap.copyOf( m_element.getRemotePeripherals() );
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IPeripheral getAvailablePeripheral( @Nonnull String name )
|
||||
{
|
||||
synchronized( m_element.getRemotePeripherals() )
|
||||
{
|
||||
return m_element.getRemotePeripherals().get( name );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user