package li.cil.oc.api.detail;
import li.cil.oc.api.network.Environment;
import li.cil.oc.api.network.Node;
import li.cil.oc.api.network.Packet;
import li.cil.oc.api.network.Visibility;
import li.cil.oc.api.network.WirelessEndpoint;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
public interface NetworkAPI {
/**
* Convenience overload for {@link #joinOrCreateNetwork(IBlockAccess, BlockPos)}.
* <p/>
* If the tile entity implements {@link Environment} its one node will be
* connected to any existing adjacent tile entity nodes. If none exist a
* new network with the specified tile entity's node as its sole entry.
* <p/>
* If the tile entity is a {@link li.cil.oc.api.network.SidedEnvironment}
* the same rules as for simple environments apply, except that the
* respective for each side is used when connecting, and each side's node
* is added to its own new network, if necessary.
*
* @param tileEntity the tile entity to initialize.
*/
void joinOrCreateNetwork(TileEntity tileEntity);
/**
* Tries to add network node(s) at the specified coordinates to adjacent
* networks.
*
* @param world the world containing the location to connect.
* @param pos the position at which to update the network.
*/
void joinOrCreateNetwork(IBlockAccess world, BlockPos pos);
/**
* Creates a new network with the specified node as its initial node.
* <p/>
* This can be used to create networks that are not bound to any tile
* entity. For example, this is used to create the internal networks of
* robots.
*
* @param node the node to create the network for.
* @throws IllegalArgumentException if the node already is in a network.
*/
void joinNewNetwork(Node node);
// ----------------------------------------------------------------------- //
/**
* Makes a wireless endpoint join the wireless network defined by the mod.
* <p/>
* OpenComputers tracks endpoints to which to send wireless packets sent
* via the {@link #sendWirelessPacket(WirelessEndpoint, double, Packet)}
* method. The packets will <em>only</em> be sent to endpoints registered
* with the network.
* <p/>
* <em>Important</em>: when your endpoint is removed from the world,
* <em>you must ensure it is also removed from the network</em>!
*
* @param endpoint the endpoint to register with the network.
*/
void joinWirelessNetwork(WirelessEndpoint endpoint);
/**
* Updates a wireless endpoint in the wireless network.
* <p/>
* This is more efficient than removing and then adding the node again, as
* it only performs the update if the position significantly changed since
* the last time the position was updated (more than 0.5 along any axis).
* <p/>
* Calling this for an endpoint that was not added before does nothing.
*
* @param endpoint the endpoint for which to update the position.
*/
void updateWirelessNetwork(WirelessEndpoint endpoint);
/**
* Removes a wireless endpoint from the wireless network.
* <p/>
* This must be called when an endpoint becomes invalid, otherwise it will
* remain in the network!
* <p/>
* Calling this for an endpoint that was not added before does nothing.
*
* @param endpoint the endpoint to remove from the wireless network.
*/
void leaveWirelessNetwork(WirelessEndpoint endpoint);
/**
* Removes a wireless endpoint from the wireless network of a specific dimension.
* <p/>
* This may be useful if the dimension of an endpoint changed and you can only
* react to that change (e.g. a player changing dimensions).
* <p/>
* Calling this for an endpoint that was not added before does nothing.
*
* @param endpoint the endpoint to remove from the wireless network.
* @param dimension the dimension with the wireless network to remove the endpoint from.
*/
void leaveWirelessNetwork(WirelessEndpoint endpoint, int dimension);
/**
* Sends a packet via the wireless network.
* <p/>
* This will look for all other registered wireless endpoints in range of
* the sender and submit the packets to them. Whether another end point is
* reached depends on the distance and potential obstacles between the
* sender and the receiver (harder blocks require a stronger signal to be
* penetrated).
*
* @param source the endpoint that is sending the message.
* @param strength the signal strength with which to send the packet.
* @param packet the packet to send.
*/
void sendWirelessPacket(WirelessEndpoint source, double strength, Packet packet);
// ----------------------------------------------------------------------- //
/**
* Factory function for creating new nodes.
* <p/>
* Use this to create a node for your environment (e.g. tile entity). This
* will return a builder that can be used to further specialize the node,
* making it either a component node (for callbacks), a connector node
* (for power interaction) or both.
* <p/>
* Example use:
* <pre>
* class YourThing extends TileEntity implements Environment {
* private ComponentConnector node_ =
* api.Network.newNode(this, Visibility.Network).
* withComponent("your_thing").
* withConnector(32).
* create();
*
* public Node node() { return node_; }
*
* // ...
* }
* </pre>
* <p/>
* Note that the <em>reachability</em> specified here is the general
* availability of the created node to other nodes in the network. Special
* rules apply to components, which have a <em>visibility</em> that is used
* to control how they can be reached from computers. For example, network
* cards have a <em>reachability</em> of <tt>Visibility.Network</tt>, to
* allow them to communicate with each other, but a <em>visibility</em> of
* <tt>Visibility.Neighbors</tt> to avoid other computers in the network
* to see the card (i.e. only the user programs running on the computer the
* card installed in can see interact with it).
*
* @param host the environment the node is created for.
* @param reachability the reachability of the node.
* @return a new node builder.
*/
Builder.NodeBuilder newNode(Environment host, Visibility reachability);
/**
* Creates a new network packet as it would be sent or received by a
* network card.
* <p/>
* These packets can be forwarded by switches and access points. For wired
* transmission they must be sent over a node's send method, with the
* message name being <tt>network.message</tt>.
*
* @param source the address of the sending node.
* @param destination the address of the destination, or <tt>null</tt>
* for a broadcast.
* @param port the port to send the packet to.
* @param data the payload of the packet.
* @return the new packet.
*/
Packet newPacket(String source, String destination, int port, Object[] data);
/**
* Re-creates a network packet from a previously stored state.
*
* @param nbt the tag to load the packet from.
* @return the loaded packet.
*/
Packet newPacket(NBTTagCompound nbt);
}