mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-12 19:20:29 +00:00
Merge pull request #205 from SquidDev-CC/feature/packet-network-api
Expose wireless network in the public API
This commit is contained in:
commit
f3c291cb4d
@ -11,6 +11,7 @@ import dan200.computercraft.api.filesystem.IMount;
|
||||
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;
|
||||
@ -736,6 +737,11 @@ public class ComputerCraft
|
||||
return upgrades;
|
||||
}
|
||||
|
||||
public IPacketNetwork getWirelessNetwork()
|
||||
{
|
||||
return WirelessNetwork.getUniversal();
|
||||
}
|
||||
|
||||
public static int createUniqueNumberedSaveDir( World world, String parentSubPath )
|
||||
{
|
||||
return IDAssigner.getNextIDFromDirectory(new File(getWorldDir(world), parentSubPath));
|
||||
|
@ -10,6 +10,7 @@ import dan200.computercraft.api.filesystem.IMount;
|
||||
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 final class ComputerCraftAPI
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ public final class ComputerCraftAPI
|
||||
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 @@ public final class ComputerCraftAPI
|
||||
private static Method computerCraft_registerMediaProvider = null;
|
||||
private static Method computerCraft_registerPermissionProvider = null;
|
||||
private static Method computerCraft_registerPocketUpgrade = null;
|
||||
private static Method computerCraft_getWirelessNetwork = null;
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.api.network;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* A packet network represents a collection of devices which can send and receive packets.
|
||||
*
|
||||
* @see Packet
|
||||
* @see IPacketReceiver
|
||||
*/
|
||||
public interface IPacketNetwork
|
||||
{
|
||||
/**
|
||||
* Add a receiver to the network.
|
||||
*
|
||||
* @param receiver The receiver to register to the network.
|
||||
*/
|
||||
void addReceiver( @Nonnull IPacketReceiver receiver );
|
||||
|
||||
/**
|
||||
* Remove a receiver from the network.
|
||||
*
|
||||
* @param receiver The device to remove from the network.
|
||||
*/
|
||||
void removeReceiver( @Nonnull IPacketReceiver receiver );
|
||||
|
||||
/**
|
||||
* Determine whether this network is wireless.
|
||||
*
|
||||
* @return Whether this network is wireless.
|
||||
*/
|
||||
boolean isWireless();
|
||||
|
||||
/**
|
||||
* Submit a packet for transmitting across the network. This will route the packet through the network, sending it
|
||||
* to all receivers within range (or any interdimensional ones).
|
||||
*
|
||||
* @param packet The packet to send.
|
||||
* @see #transmitInterdimensional(Packet)
|
||||
* @see IPacketReceiver#receiveSameDimension(Packet, double)
|
||||
*/
|
||||
void transmitSameDimension( @Nonnull Packet packet, double range );
|
||||
|
||||
/**
|
||||
* Submit a packet for transmitting across the network. This will route the packet through the network, sending it
|
||||
* to all receivers across all dimensions.
|
||||
*
|
||||
* @param packet The packet to send.
|
||||
* @see #transmitSameDimension(Packet, double)
|
||||
* @see IPacketReceiver#receiveDifferentDimension(Packet)
|
||||
*/
|
||||
void transmitInterdimensional( @Nonnull Packet packet );
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.api.network;
|
||||
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* An object on an {@link IPacketNetwork}, capable of receiving packets.
|
||||
*/
|
||||
public interface IPacketReceiver
|
||||
{
|
||||
/**
|
||||
* Get the world in which this packet receiver exists.
|
||||
*
|
||||
* @return The receivers's world.
|
||||
*/
|
||||
@Nonnull
|
||||
World getWorld();
|
||||
|
||||
/**
|
||||
* Get the position in the world at which this receiver exists.
|
||||
*
|
||||
* @return The receiver's position.
|
||||
*/
|
||||
@Nonnull
|
||||
Vec3d getPosition();
|
||||
|
||||
/**
|
||||
* Get the maximum distance this receiver can send and receive messages.
|
||||
*
|
||||
* When determining whether a receiver can receive a message, the largest distance of the packet and receiver is
|
||||
* used - ensuring it is within range. If the packet or receiver is inter-dimensional, then the packet will always
|
||||
* be received.
|
||||
*
|
||||
* @return The maximum distance this device can send and receive messages.
|
||||
* @see #isInterdimensional()
|
||||
* @see #receiveSameDimension(Packet packet, double)
|
||||
* @see IPacketNetwork#transmitInterdimensional(Packet)
|
||||
*/
|
||||
double getRange();
|
||||
|
||||
/**
|
||||
* Determine whether this receiver can receive packets from other dimensions.
|
||||
*
|
||||
* A device will receive an inter-dimensional packet if either it or the sending device is inter-dimensional.
|
||||
*
|
||||
* @return Whether this receiver receives packets from other dimensions.
|
||||
* @see #getRange()
|
||||
* @see #receiveDifferentDimension(Packet)
|
||||
* @see IPacketNetwork#transmitInterdimensional(Packet)
|
||||
*/
|
||||
boolean isInterdimensional();
|
||||
|
||||
/**
|
||||
* Receive a network packet from the same dimension.
|
||||
*
|
||||
* @param packet The packet to receive. Generally you should check that you are listening on the given channel and,
|
||||
* if so, queue the appropriate modem event.
|
||||
* @param distance The distance this packet has travelled from the source.
|
||||
* @see Packet
|
||||
* @see #getRange()
|
||||
* @see IPacketNetwork#transmitSameDimension(Packet, double)
|
||||
* @see IPacketNetwork#transmitInterdimensional(Packet)
|
||||
*/
|
||||
void receiveSameDimension( @Nonnull Packet packet, double distance );
|
||||
|
||||
/**
|
||||
* Receive a network packet from a different dimension.
|
||||
*
|
||||
* @param packet The packet to receive. Generally you should check that you are listening on the given channel and,
|
||||
* if so, queue the appropriate modem event.
|
||||
* @see Packet
|
||||
* @see IPacketNetwork#transmitInterdimensional(Packet)
|
||||
* @see IPacketNetwork#transmitSameDimension(Packet, double)
|
||||
* @see #isInterdimensional()
|
||||
*/
|
||||
void receiveDifferentDimension( @Nonnull Packet packet );
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.api.network;
|
||||
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* An object on a {@link IPacketNetwork}, capable of sending packets.
|
||||
*/
|
||||
public interface IPacketSender
|
||||
{
|
||||
/**
|
||||
* Get the world in which this packet sender exists.
|
||||
*
|
||||
* @return The sender's world.
|
||||
*/
|
||||
@Nonnull
|
||||
World getWorld();
|
||||
|
||||
/**
|
||||
* Get the position in the world at which this sender exists.
|
||||
*
|
||||
* @return The sender's position.
|
||||
*/
|
||||
@Nonnull
|
||||
Vec3d getPosition();
|
||||
|
||||
/**
|
||||
* Get some sort of identification string for this sender. This does not strictly need to be unique, but you
|
||||
* should be able to extract some identifiable information from it.
|
||||
*
|
||||
* @return This device's id.
|
||||
*/
|
||||
@Nonnull
|
||||
String getSenderID();
|
||||
}
|
118
src/main/java/dan200/computercraft/api/network/Packet.java
Normal file
118
src/main/java/dan200/computercraft/api/network/Packet.java
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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.api.network;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a packet which may be sent across a {@link IPacketNetwork}.
|
||||
*
|
||||
* @see IPacketSender
|
||||
* @see IPacketNetwork#transmitSameDimension(Packet, double)
|
||||
* @see IPacketNetwork#transmitInterdimensional(Packet)
|
||||
* @see IPacketReceiver#receiveDifferentDimension(Packet)
|
||||
* @see IPacketReceiver#receiveSameDimension(Packet, double)
|
||||
*/
|
||||
public class Packet
|
||||
{
|
||||
private final int m_channel;
|
||||
private final int m_replyChannel;
|
||||
private final Object m_payload;
|
||||
|
||||
private final IPacketSender m_sender;
|
||||
|
||||
/**
|
||||
* Create a new packet, ready for transmitting across the network.
|
||||
*
|
||||
* @param channel The channel to send the packet along. Receiving devices should only process packets from on
|
||||
* channels they are listening to.
|
||||
* @param replyChannel The channel to reply on.
|
||||
* @param payload The contents of this packet. This should be a "valid" Lua object, safe for queuing as an
|
||||
* event or returning from a peripheral call.
|
||||
* @param sender The object which sent this packet.
|
||||
*/
|
||||
public Packet( int channel, int replyChannel, @Nullable Object payload, @Nonnull IPacketSender sender )
|
||||
{
|
||||
Preconditions.checkNotNull( sender, "sender cannot be null" );
|
||||
|
||||
m_channel = channel;
|
||||
m_replyChannel = replyChannel;
|
||||
m_payload = payload;
|
||||
m_sender = sender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channel this packet is sent along. Receivers should generally only process packets from on channels they
|
||||
* are listening to.
|
||||
*
|
||||
* @return This packet's channel.
|
||||
*/
|
||||
public int getChannel()
|
||||
{
|
||||
return m_channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* The channel to reply on. Objects which will reply should send it along this channel.
|
||||
*
|
||||
* @return This channel to reply on.
|
||||
*/
|
||||
public int getReplyChannel()
|
||||
{
|
||||
return m_replyChannel;
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual data of this packet. This should be a "valid" Lua object, safe for queuing as an
|
||||
* event or returning from a peripheral call.
|
||||
*
|
||||
* @return The packet's payload
|
||||
*/
|
||||
@Nullable
|
||||
public Object getPayload()
|
||||
{
|
||||
return m_payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* The object which sent this message.
|
||||
*
|
||||
* @return The sending object.
|
||||
*/
|
||||
@Nonnull
|
||||
public IPacketSender getSender()
|
||||
{
|
||||
return m_sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Object o )
|
||||
{
|
||||
if( this == o ) return true;
|
||||
if( o == null || getClass() != o.getClass() ) return false;
|
||||
|
||||
Packet packet = (Packet) o;
|
||||
|
||||
if( m_channel != packet.m_channel ) return false;
|
||||
if( m_replyChannel != packet.m_replyChannel ) return false;
|
||||
if( m_payload != null ? !m_payload.equals( packet.m_payload ) : packet.m_payload != null ) return false;
|
||||
return m_sender.equals( packet.m_sender );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int result;
|
||||
result = m_channel;
|
||||
result = 31 * result + m_replyChannel;
|
||||
result = 31 * result + (m_payload != null ? m_payload.hashCode() : 0);
|
||||
result = 31 * result + m_sender.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
@API( owner="ComputerCraft", provides="ComputerCraft|API|Network", apiVersion="${version}" )
|
||||
package dan200.computercraft.api.network;
|
||||
|
||||
import net.minecraftforge.fml.common.API;
|
@ -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();
|
||||
}
|
@ -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 );
|
||||
}
|
@ -8,83 +8,25 @@ package dan200.computercraft.shared.peripheral.modem;
|
||||
|
||||
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 abstract class 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 @@ public abstract class ModemPeripheral
|
||||
// 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 @@ public abstract class ModemPeripheral
|
||||
setNetwork( getNetwork() );
|
||||
}
|
||||
|
||||
protected abstract World getWorld();
|
||||
|
||||
protected abstract Vec3d getPosition();
|
||||
|
||||
public synchronized void destroy()
|
||||
{
|
||||
setNetwork( null );
|
||||
@ -151,53 +82,45 @@ public abstract class ModemPeripheral
|
||||
}
|
||||
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 abstract class ModemPeripheral
|
||||
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 abstract class ModemPeripheral
|
||||
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 abstract class ModemPeripheral
|
||||
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 abstract class ModemPeripheral
|
||||
{
|
||||
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,15 @@ public abstract class ModemPeripheral
|
||||
Vec3d position = getPosition();
|
||||
if( world != null && position != null && m_network != null)
|
||||
{
|
||||
m_network.transmit( channel, replyChannel, payload, world, position, getTransmitRange(), isInterdimensional(), this );
|
||||
Packet packet = new Packet( channel, replyChannel, payload, this );
|
||||
if( isInterdimensional() )
|
||||
{
|
||||
m_network.transmitInterdimensional( packet );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_network.transmitSameDimension( packet, getRange() );
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -377,10 +289,7 @@ public abstract class ModemPeripheral
|
||||
{
|
||||
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 +303,22 @@ public abstract class ModemPeripheral
|
||||
}
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ import net.minecraft.util.EnumFacing;
|
||||
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 class TileAdvancedModem extends TileModemBase
|
||||
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() );
|
||||
|
@ -12,6 +12,9 @@ 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.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.io.File;
|
||||
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 class TileCable extends TileModemBase
|
||||
}
|
||||
|
||||
@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,8 +238,8 @@ public class TileCable extends TileModemBase
|
||||
|
||||
// Members
|
||||
|
||||
private final Map<Integer, Set<IReceiver>> m_receivers;
|
||||
private final Queue<Packet> m_transmitQueue;
|
||||
private final Set<IPacketReceiver> m_receivers;
|
||||
private final Queue<PacketWrapper> m_transmitQueue;
|
||||
|
||||
private boolean m_peripheralAccessAllowed;
|
||||
private int m_attachedPeripheralID;
|
||||
@ -248,8 +253,8 @@ public class TileCable extends TileModemBase
|
||||
|
||||
public TileCable()
|
||||
{
|
||||
m_receivers = new HashMap<Integer, Set<IReceiver>>();
|
||||
m_transmitQueue = new LinkedList<Packet>();
|
||||
m_receivers = new HashSet<IPacketReceiver>();
|
||||
m_transmitQueue = new LinkedList<PacketWrapper>();
|
||||
|
||||
m_peripheralAccessAllowed = false;
|
||||
m_attachedPeripheralID = -1;
|
||||
@ -564,7 +569,7 @@ public class TileCable extends TileModemBase
|
||||
{
|
||||
while( m_transmitQueue.peek() != null )
|
||||
{
|
||||
Packet p = m_transmitQueue.remove();
|
||||
PacketWrapper p = m_transmitQueue.remove();
|
||||
if( p != null )
|
||||
{
|
||||
dispatchPacket( p );
|
||||
@ -573,53 +578,45 @@ public class TileCable extends TileModemBase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 transmitSameDimension( @Nonnull Packet packet, double range )
|
||||
{
|
||||
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( new PacketWrapper( packet, range ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void transmitInterdimensional( @Nonnull Packet packet )
|
||||
{
|
||||
synchronized( m_transmitQueue )
|
||||
{
|
||||
m_transmitQueue.offer( new PacketWrapper( packet, Double.MAX_VALUE ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWireless()
|
||||
{
|
||||
@ -726,21 +723,28 @@ public class TileCable extends TileModemBase
|
||||
// private stuff
|
||||
|
||||
// Packet sending
|
||||
|
||||
private class Packet
|
||||
|
||||
private static class PacketWrapper
|
||||
{
|
||||
public int channel;
|
||||
public int replyChannel;
|
||||
public Object payload;
|
||||
public Object senderObject;
|
||||
final Packet m_packet;
|
||||
final double m_range;
|
||||
|
||||
private PacketWrapper( Packet m_packet, double m_range )
|
||||
{
|
||||
this.m_packet = m_packet;
|
||||
this.m_range = m_range;
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchPacket( final Packet packet )
|
||||
private void dispatchPacket( final PacketWrapper packet )
|
||||
{
|
||||
searchNetwork( new ICableVisitor() {
|
||||
public void visit( TileCable modem, int distance )
|
||||
{
|
||||
modem.receivePacket( packet, distance );
|
||||
if( distance <= packet.m_range)
|
||||
{
|
||||
modem.receivePacket( packet.m_packet, distance );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
@ -749,13 +753,9 @@ public class TileCable extends TileModemBase
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,14 +33,16 @@ public class TileWirelessModem extends TileModemBase
|
||||
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() );
|
||||
|
@ -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 abstract class WirelessModemPeripheral extends ModemPeripheral
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInterdimensional()
|
||||
public boolean isInterdimensional()
|
||||
{
|
||||
return m_advanced;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double getTransmitRange()
|
||||
public double getRange()
|
||||
{
|
||||
if( m_advanced )
|
||||
{
|
||||
@ -56,7 +57,7 @@ public abstract class WirelessModemPeripheral extends ModemPeripheral
|
||||
}
|
||||
|
||||
@Override
|
||||
protected INetwork getNetwork()
|
||||
protected IPacketNetwork getNetwork()
|
||||
{
|
||||
return WirelessNetwork.getUniversal();
|
||||
}
|
||||
|
@ -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,65 @@ public class WirelessNetwork implements INetwork
|
||||
{
|
||||
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 transmitSameDimension( @Nonnull Packet packet, double range )
|
||||
{
|
||||
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, range, false );
|
||||
}
|
||||
}
|
||||
|
||||
private void tryTransmit( IReceiver receiver, int replyChannel, Object payload, World world, Vec3d pos, double range, boolean interdimensional, Object senderObject )
|
||||
|
||||
@Override
|
||||
public synchronized void transmitInterdimensional( @Nonnull Packet packet )
|
||||
{
|
||||
if( receiver.getWorld() == world )
|
||||
Preconditions.checkNotNull( packet, "packet cannot be null" );
|
||||
for (IPacketReceiver device : m_receivers)
|
||||
{
|
||||
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 ) )
|
||||
tryTransmit( device, packet, 0, true );
|
||||
}
|
||||
}
|
||||
|
||||
private void tryTransmit( IPacketReceiver receiver, Packet packet, double range, boolean interdimensional )
|
||||
{
|
||||
IPacketSender sender = packet.getSender();
|
||||
if( receiver.getWorld() == sender.getWorld() )
|
||||
{
|
||||
double receiveRange = Math.max( range, receiver.getRange() ); // Ensure range is symmetrical
|
||||
double distanceSq = receiver.getPosition().squareDistanceTo( sender.getPosition() );
|
||||
if( interdimensional || receiver.isInterdimensional() || distanceSq <= (receiveRange * receiveRange) )
|
||||
{
|
||||
receiver.receiveSameDimension( replyChannel, payload, Math.sqrt( distanceSq ), senderObject );
|
||||
receiver.receiveSameDimension( packet, Math.sqrt( distanceSq ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( interdimensional || receiver.isInterdimensional() )
|
||||
{
|
||||
receiver.receiveDifferentDimension( replyChannel, payload, senderObject );
|
||||
receiver.receiveDifferentDimension( packet );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 dan200.computercraft.shared.peripheral.modem.WirelessModemPeripheral;
|
||||
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 class PocketModemPeripheral extends WirelessModemPeripheral
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
protected World getWorld()
|
||||
public World getWorld()
|
||||
{
|
||||
return m_world;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
protected Vec3d getPosition()
|
||||
public Vec3d getPosition()
|
||||
{
|
||||
if( m_world != null )
|
||||
{
|
||||
|
@ -42,14 +42,16 @@ public class TurtleModem implements ITurtleUpgrade
|
||||
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(
|
||||
|
Loading…
Reference in New Issue
Block a user