1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-06-26 07:03:22 +00:00

Switch from using INetwork to IPacketNetwork

This commit is contained in:
SquidDev 2017-05-06 21:19:55 +01:00
parent e6ef1cfadd
commit a328308f67
12 changed files with 165 additions and 280 deletions

View File

@ -11,6 +11,7 @@
import dan200.computercraft.api.filesystem.IWritableMount;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.media.IMediaProvider;
import dan200.computercraft.api.network.IPacketNetwork;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.api.permissions.ITurtlePermissionProvider;
@ -702,6 +703,11 @@ public static Iterable<IPocketUpgrade> getVanillaPocketUpgrades() {
return upgrades;
}
public IPacketNetwork getWirelessNetwork()
{
return WirelessNetwork.getUniversal();
}
public static int createUniqueNumberedSaveDir( World world, String parentSubPath )
{
return IDAssigner.getNextIDFromDirectory(new File(getWorldDir(world), parentSubPath));

View File

@ -10,6 +10,7 @@
import dan200.computercraft.api.filesystem.IWritableMount;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.media.IMediaProvider;
import dan200.computercraft.api.network.IPacketNetwork;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
@ -289,6 +290,27 @@ public static void registerPocketUpgrade( @Nonnull IPocketUpgrade upgrade )
}
}
/**
* Attempt to get the game-wide wireless network.
*
* @return The global wireless network, or {@code null} if it could not be fetched.
*/
public static IPacketNetwork getWirelessNetwork()
{
findCC();
if( computerCraft_getWirelessNetwork != null )
{
try
{
return (IPacketNetwork) computerCraft_getWirelessNetwork.invoke( null );
} catch (Exception e) {
// It failed;
}
}
return null;
}
// The functions below here are private, and are used to interface with the non-API ComputerCraft classes.
// Reflection is used here so you can develop your mod without decompiling ComputerCraft and including
// it in your solution, and so your mod won't crash if ComputerCraft is installed.
@ -330,6 +352,8 @@ private static void findCC()
computerCraft_registerPocketUpgrade = findCCMethod( "registerPocketUpgrade", new Class<?>[] {
IPocketUpgrade.class
} );
computerCraft_getWirelessNetwork = findCCMethod( "getWirelessNetwork", new Class<?>[] {
} );
} catch( Exception e ) {
System.out.println( "ComputerCraftAPI: ComputerCraft not found." );
} finally {
@ -365,4 +389,5 @@ private static Method findCCMethod( String name, Class<?>[] args )
private static Method computerCraft_registerMediaProvider = null;
private static Method computerCraft_registerPermissionProvider = null;
private static Method computerCraft_registerPocketUpgrade = null;
private static Method computerCraft_getWirelessNetwork = null;
}

View File

@ -1,18 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.peripheral.modem;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public interface INetwork
{
void addReceiver( IReceiver receiver );
void removeReceiver( IReceiver receiver );
void transmit( int channel, int replyChannel, Object payload, World world, Vec3d pos, double range, boolean interdimensional, Object senderObject );
boolean isWireless();
}

View File

@ -1,20 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.peripheral.modem;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public interface IReceiver
{
int getChannel();
World getWorld();
Vec3d getWorldPosition();
boolean isInterdimensional();
double getReceiveRange();
void receiveSameDimension( int replyChannel, Object payload, double distance, Object senderObject );
void receiveDifferentDimension( int replyChannel, Object payload, Object senderObject );
}

View File

@ -8,83 +8,25 @@
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.network.IPacketNetwork;
import dan200.computercraft.api.network.IPacketReceiver;
import dan200.computercraft.api.network.IPacketSender;
import dan200.computercraft.api.network.Packet;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import gnu.trove.set.TIntSet;
import gnu.trove.set.hash.TIntHashSet;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import java.util.HashMap;
import java.util.Map;
public abstract class ModemPeripheral
implements IPeripheral
{
private static class SingleChannelReceiver implements IReceiver
{
private ModemPeripheral m_owner;
private int m_channel;
public SingleChannelReceiver( ModemPeripheral owner, int channel )
{
m_owner = owner;
m_channel = channel;
}
// IReceiver implementation
@Override
public int getChannel()
{
return m_channel;
}
@Override
public World getWorld()
{
return m_owner.getWorld();
}
@Override
public Vec3d getWorldPosition()
{
return m_owner.getWorldPosition();
}
@Override
public boolean isInterdimensional()
{
return m_owner.isInterdimensional();
}
@Override
public double getReceiveRange()
{
return m_owner.getReceiveRange();
}
@Override
public void receiveSameDimension( int replyChannel, Object payload, double distance, Object senderObject )
{
if( senderObject != m_owner )
{
m_owner.receiveSameDimension( m_channel, replyChannel, payload, distance );
}
}
@Override
public void receiveDifferentDimension( int replyChannel, Object payload, Object senderObject )
{
if( senderObject != m_owner )
{
m_owner.receiveDifferentDimension( m_channel, replyChannel, payload );
}
}
}
private INetwork m_network;
implements IPeripheral, IPacketSender, IPacketReceiver
{
private IPacketNetwork m_network;
private IComputerAccess m_computer;
private final Map<Integer, IReceiver> m_channels;
private final TIntSet m_channels;
private boolean m_open;
private boolean m_changed;
@ -93,23 +35,19 @@ public ModemPeripheral()
{
m_network = null;
m_computer = null;
m_channels = new HashMap<Integer, IReceiver>();
m_channels = new TIntHashSet();
m_open = false;
m_changed = true;
}
private synchronized void setNetwork( INetwork network )
private synchronized void setNetwork( IPacketNetwork network )
{
if( m_network != network )
{
// Leave old network
if( m_network != null )
{
for( IReceiver iReceiver : m_channels.values() )
{
m_network.removeReceiver( iReceiver );
}
m_network.removeReceiver( this );
}
// Set new network
@ -118,10 +56,7 @@ private synchronized void setNetwork( INetwork network )
// Join new network
if( m_network != null )
{
for( IReceiver iReceiver : m_channels.values() )
{
m_network.addReceiver( iReceiver );
}
m_network.addReceiver( this );
}
}
}
@ -131,10 +66,6 @@ protected void switchNetwork()
setNetwork( getNetwork() );
}
protected abstract World getWorld();
protected abstract Vec3d getPosition();
public synchronized void destroy()
{
setNetwork( null );
@ -151,53 +82,45 @@ public synchronized boolean pollChanged()
}
return false;
}
protected abstract double getTransmitRange();
protected abstract boolean isInterdimensional();
public synchronized boolean isActive()
{
return (m_computer != null) && m_open;
}
public synchronized Vec3d getWorldPosition()
{
return getPosition();
}
public synchronized double getReceiveRange()
{
return getTransmitRange();
}
public void receiveSameDimension( int channel, int replyChannel, Object payload, double distance )
@Override
public void receiveSameDimension( @Nonnull Packet packet, double distance )
{
if( packet.getSender() == this ) return;
synchronized (m_channels)
{
if( m_computer != null && m_channels.containsKey( channel ) )
if( m_computer != null && m_channels.contains( packet.getChannel() ) )
{
m_computer.queueEvent( "modem_message", new Object[] {
m_computer.getAttachmentName(), channel, replyChannel, payload, distance
m_computer.getAttachmentName(), packet.getChannel(), packet.getReplyChannel(), packet.getPayload(), distance
} );
}
}
}
public void receiveDifferentDimension( int channel, int replyChannel, Object payload )
@Override
public void receiveDifferentDimension( @Nonnull Packet packet )
{
if( packet.getSender() == this ) return;
synchronized (m_channels)
{
if( m_computer != null && m_channels.containsKey( channel ) )
if( m_computer != null && m_channels.contains( packet.getChannel() ) )
{
m_computer.queueEvent( "modem_message", new Object[] {
m_computer.getAttachmentName(), channel, replyChannel, payload
m_computer.getAttachmentName(), packet.getChannel(), packet.getReplyChannel(), packet.getPayload()
} );
}
}
}
protected abstract INetwork getNetwork();
protected abstract IPacketNetwork getNetwork();
// IPeripheral implementation
@ -247,19 +170,14 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
int channel = parseChannel( arguments, 0 );
synchronized( this )
{
if( !m_channels.containsKey( channel ) )
if( !m_channels.contains( channel ) )
{
if( m_channels.size() >= 128 )
{
throw new LuaException( "Too many open channels" );
}
IReceiver receiver = new SingleChannelReceiver( this, channel );
m_channels.put( channel, receiver );
if( m_network != null )
{
m_network.addReceiver( receiver );
}
m_channels.add( channel );
if( !m_open )
{
m_open = true;
@ -275,7 +193,7 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
int channel = parseChannel( arguments, 0 );
synchronized( this )
{
boolean open = m_channels.containsKey( channel );
boolean open = m_channels.contains( channel );
return new Object[] { open };
}
}
@ -285,15 +203,8 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
int channel = parseChannel( arguments, 0 );
synchronized( this )
{
if( m_channels.containsKey( channel ) )
if( m_channels.remove( channel ) )
{
IReceiver receiver = m_channels.get( channel );
if( m_network != null )
{
m_network.removeReceiver( receiver );
}
m_channels.remove( channel );
if( m_channels.size() == 0 )
{
m_open = false;
@ -310,13 +221,6 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
{
if( m_channels.size() > 0 )
{
if( m_network != null )
{
for( IReceiver iReceiver : m_channels.values() )
{
m_network.removeReceiver( iReceiver );
}
}
m_channels.clear();
if( m_open )
@ -340,7 +244,7 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
Vec3d position = getPosition();
if( world != null && position != null && m_network != null)
{
m_network.transmit( channel, replyChannel, payload, world, position, getTransmitRange(), isInterdimensional(), this );
m_network.transmit( new Packet( channel, replyChannel, payload, getRange(), isInterdimensional(), this ) );
}
}
return null;
@ -377,10 +281,7 @@ public synchronized void detach( @Nonnull IComputerAccess computer )
{
if( m_network != null )
{
for( IReceiver iReceiver : m_channels.values() )
{
m_network.removeReceiver( iReceiver );
}
m_network.removeReceiver( this );
m_channels.clear();
m_network = null;
}
@ -394,11 +295,22 @@ public synchronized void detach( @Nonnull IComputerAccess computer )
}
}
@Override
public abstract boolean equals( IPeripheral other );
public IComputerAccess getComputer()
{
return m_computer;
}
@Nonnull
@Override
public String getSenderID()
{
if( m_computer == null )
{
return "unknown";
}
else
{
return m_computer.getID() + "_" + m_computer.getAttachmentName();
}
}
}

View File

@ -13,6 +13,8 @@
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
public class TileAdvancedModem extends TileModemBase
{
// Statics
@ -27,14 +29,16 @@ public Peripheral( TileModemBase entity )
m_entity = entity;
}
@Nonnull
@Override
public World getWorld()
{
return m_entity.getWorld();
}
@Nonnull
@Override
protected Vec3d getPosition()
public Vec3d getPosition()
{
BlockPos pos = m_entity.getPos().offset( m_entity.getDirection() );
return new Vec3d( (double)pos.getX(), (double)pos.getY(), (double)pos.getZ() );

View File

@ -12,6 +12,9 @@
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.IPacketReceiver;
import dan200.computercraft.api.network.Packet;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.common.BlockGeneric;
@ -38,7 +41,7 @@
import java.util.*;
public class TileCable extends TileModemBase
implements INetwork
implements IPacketNetwork
{
private static final double MIN = 0.375;
private static final double MAX = 1 - MIN;
@ -65,31 +68,33 @@ public Peripheral( TileCable entity )
}
@Override
protected boolean isInterdimensional()
public boolean isInterdimensional()
{
return false;
}
@Override
protected double getTransmitRange()
public double getRange()
{
return 256.0;
}
@Override
protected INetwork getNetwork()
protected IPacketNetwork getNetwork()
{
return m_entity;
}
@Nonnull
@Override
protected World getWorld()
public World getWorld()
{
return m_entity.getWorld();
}
@Nonnull
@Override
protected Vec3d getPosition()
public Vec3d getPosition()
{
EnumFacing direction = m_entity.getDirection();
BlockPos pos = m_entity.getPos().offset( direction );
@ -233,7 +238,7 @@ public boolean equals( IPeripheral other )
// Members
private final Map<Integer, Set<IReceiver>> m_receivers;
private final Set<IPacketReceiver> m_receivers;
private final Queue<Packet> m_transmitQueue;
private boolean m_peripheralAccessAllowed;
@ -248,7 +253,7 @@ public boolean equals( IPeripheral other )
public TileCable()
{
m_receivers = new HashMap<Integer, Set<IReceiver>>();
m_receivers = new HashSet<IPacketReceiver>();
m_transmitQueue = new LinkedList<Packet>();
m_peripheralAccessAllowed = false;
@ -573,50 +578,33 @@ public void update()
}
}
}
// INetwork implementation
// IPacketNetwork implementation
@Override
public void addReceiver( IReceiver receiver )
public void addReceiver( @Nonnull IPacketReceiver receiver )
{
synchronized( m_receivers )
{
int channel = receiver.getChannel();
Set<IReceiver> receivers = m_receivers.get( channel );
if( receivers == null )
{
receivers = new HashSet<IReceiver>();
m_receivers.put( channel, receivers );
}
receivers.add( receiver );
m_receivers.add( receiver );
}
}
@Override
public void removeReceiver( IReceiver receiver )
public void removeReceiver( @Nonnull IPacketReceiver receiver )
{
synchronized( m_receivers )
{
int channel = receiver.getChannel();
Set<IReceiver> receivers = m_receivers.get( channel );
if( receivers != null )
{
receivers.remove( receiver );
}
m_receivers.remove( receiver );
}
}
@Override
public void transmit( int channel, int replyChannel, Object payload, World world, Vec3d pos, double range, boolean interdimensional, Object senderObject )
public void transmit( @Nonnull Packet packet )
{
Packet p = new Packet();
p.channel = channel;
p.replyChannel = replyChannel;
p.payload = payload;
p.senderObject = senderObject;
synchronized( m_transmitQueue )
{
m_transmitQueue.offer(p);
m_transmitQueue.offer( packet );
}
}
@ -726,14 +714,6 @@ public void visit( TileCable modem, int distance )
// private stuff
// Packet sending
private class Packet
{
public int channel;
public int replyChannel;
public Object payload;
public Object senderObject;
}
private void dispatchPacket( final Packet packet )
{
@ -749,13 +729,9 @@ private void receivePacket( Packet packet, int distanceTravelled )
{
synchronized( m_receivers )
{
Set<IReceiver> receivers = m_receivers.get( packet.channel );
if( receivers != null )
for (IPacketReceiver device : m_receivers)
{
for( IReceiver receiver : receivers )
{
receiver.receiveSameDimension( packet.replyChannel, packet.payload, (double) distanceTravelled, packet.senderObject );
}
device.receiveSameDimension( packet, distanceTravelled );
}
}
}

View File

@ -33,14 +33,16 @@ public Peripheral( TileModemBase entity )
m_entity = entity;
}
@Nonnull
@Override
protected World getWorld()
public World getWorld()
{
return m_entity.getWorld();
}
@Nonnull
@Override
protected Vec3d getPosition()
public Vec3d getPosition()
{
BlockPos pos = m_entity.getPos().offset( m_entity.getDirection() );
return new Vec3d( (double)pos.getX(), (double)pos.getY(), (double)pos.getZ() );

View File

@ -7,6 +7,7 @@
package dan200.computercraft.shared.peripheral.modem;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.network.IPacketNetwork;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
@ -20,13 +21,13 @@ public WirelessModemPeripheral( boolean advanced )
}
@Override
protected boolean isInterdimensional()
public boolean isInterdimensional()
{
return m_advanced;
}
@Override
protected double getTransmitRange()
public double getRange()
{
if( m_advanced )
{
@ -56,7 +57,7 @@ protected double getTransmitRange()
}
@Override
protected INetwork getNetwork()
protected IPacketNetwork getNetwork()
{
return WirelessNetwork.getUniversal();
}

View File

@ -6,12 +6,17 @@
package dan200.computercraft.shared.peripheral.modem;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import com.google.common.base.Preconditions;
import dan200.computercraft.api.network.IPacketNetwork;
import dan200.computercraft.api.network.IPacketReceiver;
import dan200.computercraft.api.network.IPacketSender;
import dan200.computercraft.api.network.Packet;
import java.util.*;
import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.Set;
public class WirelessNetwork implements INetwork
public class WirelessNetwork implements IPacketNetwork
{
private static WirelessNetwork s_universalNetwork = null;
@ -28,68 +33,55 @@ public static void resetNetworks()
{
s_universalNetwork = null;
}
private Map<Integer, Set<IReceiver>> m_receivers;
private final Set<IPacketReceiver> m_receivers;
private WirelessNetwork()
{
m_receivers = new HashMap<Integer, Set<IReceiver>>();
m_receivers = new HashSet<IPacketReceiver>();
}
@Override
public synchronized void addReceiver( IReceiver receiver )
public synchronized void addReceiver( @Nonnull IPacketReceiver receiver )
{
int channel = receiver.getChannel();
Set<IReceiver> receivers = m_receivers.get( channel );
if( receivers == null )
{
receivers = new HashSet<IReceiver>();
m_receivers.put( channel, receivers );
}
receivers.add( receiver );
Preconditions.checkNotNull( receiver, "device cannot be null" );
m_receivers.add( receiver );
}
@Override
public synchronized void removeReceiver( IReceiver receiver )
public synchronized void removeReceiver( @Nonnull IPacketReceiver receiver )
{
int channel = receiver.getChannel();
Set<IReceiver> receivers = m_receivers.get( channel );
if( receivers != null )
{
receivers.remove( receiver );
}
Preconditions.checkNotNull( receiver, "device cannot be null" );
m_receivers.remove( receiver );
}
@Override
public synchronized void transmit( int channel, int replyChannel, Object payload, World world, Vec3d pos, double range, boolean interdimensional, Object senderObject )
public synchronized void transmit( @Nonnull Packet packet )
{
Set<IReceiver> receivers = m_receivers.get( channel );
if( receivers != null )
Preconditions.checkNotNull( packet, "packet cannot be null" );
for (IPacketReceiver device : m_receivers)
{
for( IReceiver receiver : receivers )
{
tryTransmit( receiver, replyChannel, payload, world, pos, range, interdimensional, senderObject );
}
tryTransmit( device, packet );
}
}
private void tryTransmit( IReceiver receiver, int replyChannel, Object payload, World world, Vec3d pos, double range, boolean interdimensional, Object senderObject )
private void tryTransmit( IPacketReceiver receiver, Packet packet )
{
if( receiver.getWorld() == world )
IPacketSender sender = packet.getSender();
if( receiver.getWorld() == sender.getWorld() )
{
Vec3d position = receiver.getWorldPosition();
double receiveRange = Math.max( range, receiver.getReceiveRange() ); // Ensure range is symmetrical
double distanceSq = position.squareDistanceTo( pos );
if( interdimensional || receiver.isInterdimensional() || distanceSq <= ( receiveRange * receiveRange ) )
double receiveRange = Math.max( packet.getRange(), receiver.getRange() ); // Ensure range is symmetrical
double distanceSq = receiver.getPosition().squareDistanceTo( sender.getPosition() );
if( packet.isInterdimensional() || receiver.isInterdimensional() || distanceSq <= (receiveRange * receiveRange) )
{
receiver.receiveSameDimension( replyChannel, payload, Math.sqrt( distanceSq ), senderObject );
receiver.receiveSameDimension( packet, Math.sqrt( distanceSq ) );
}
}
else
{
if( interdimensional || receiver.isInterdimensional() )
if( packet.isInterdimensional() || receiver.isInterdimensional() )
{
receiver.receiveDifferentDimension( replyChannel, payload, senderObject );
receiver.receiveDifferentDimension( packet );
}
}
}

View File

@ -1,3 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.pocket.peripherals;
import dan200.computercraft.api.peripheral.IPeripheral;
@ -5,11 +10,7 @@
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
import javax.annotation.Nonnull;
public class PocketModemPeripheral extends WirelessModemPeripheral
{
@ -33,14 +34,16 @@ public void setLocation( World world, double x, double y, double z )
}
}
@Nonnull
@Override
protected World getWorld()
public World getWorld()
{
return m_world;
}
@Nonnull
@Override
protected Vec3d getPosition()
public Vec3d getPosition()
{
if( m_world != null )
{

View File

@ -42,14 +42,16 @@ public Peripheral( ITurtleAccess turtle, boolean advanced )
m_turtle = turtle;
}
@Nonnull
@Override
protected World getWorld()
public World getWorld()
{
return m_turtle.getWorld();
}
@Nonnull
@Override
protected Vec3d getPosition()
public Vec3d getPosition()
{
BlockPos turtlePos = m_turtle.getPosition();
return new Vec3d(