package speedytools.common.network.multipart;
import net.minecraftforge.fml.relauncher.Side;
import speedytools.common.selections.BlockVoxelMultiSelector;
import speedytools.common.SpeedyToolsOptions;
import speedytools.common.network.Packet250Types;
import speedytools.common.selections.VoxelSelectionWithOrigin;
import speedytools.common.utilities.ErrorLog;
import java.io.*;
/**
* User: The Grey Ghost
* Date: 28/03/14
*
*
* Used to transmit a VoxelSelection
* Basic usage:
* On the client side (the sender)
* (1) createSenderPacket to create a SelectionPacket from the voxel selection
* (2) Transmit the SelectionPacket as per MultipartPacket
* On the server side (the receiver)
* (1) give SelectionPacketCreator to the MultipartPacket factory
* (1) createReceiverPacket to create the packet from the incoming Packet250
* (2) continue receiving the SelectionPacket as per MultipartPacket
* (3) once complete, retrieveVoxelSelection to extract the VoxelSelection
*/
public class SelectionPacket extends MultipartPacket
{
/**
* Creates a new SelectionPacket for the supplied selection
* @param selection
* @return the new SelectionPacket, or null for failure
*/
public static SelectionPacket createSenderPacket(BlockVoxelMultiSelector selection, Side senderSide)
{
final int SEGMENT_SIZE = SpeedyToolsOptions.getSelectionPacketFragmentSize();
SelectionPacket newPacket = new SelectionPacket(Packet250Types.PACKET250_SELECTION_PACKET, senderSide, SEGMENT_SIZE);
ByteArrayOutputStream bos = selection.writeToBytes();
if (bos == null) return null;
newPacket.setRawDataForSending(bos.toByteArray());
return newPacket;
}
public static SelectionPacket createReceiverPacket(Packet250MultipartSegment packet)
{
SelectionPacket newPacket;
try {
newPacket = new SelectionPacket(packet);
newPacket.processIncomingSegment(packet);
return newPacket;
} catch (IOException ioe) {
ErrorLog.defaultLog().info("Failed to createReceiverPacket, due to exception " + ioe.toString());
return null;
}
}
/**
* Once the packet is completely received, can be used to extract the VoxelSelection from it
* @return the received VoxelSelection, or null if a problem
*/
public VoxelSelectionWithOrigin retrieveVoxelSelection()
{
byte [] rawDataCopy = getRawDataCopy();
if (rawDataCopy == null) return null;
VoxelSelectionWithOrigin voxelSelection = new VoxelSelectionWithOrigin(0, 0, 0, 1, 1, 1);
ByteArrayInputStream inputStream = new ByteArrayInputStream(rawDataCopy);
boolean success = voxelSelection.readFromBytes(inputStream);
return success ? voxelSelection : null;
}
/**
* Create a selection packet from in incoming segment
* @param packet
* @throws IOException
*/
protected SelectionPacket(Packet250MultipartSegment packet) throws IOException
{
super(packet);
}
/**
* Create a selection packet to be sent to a receiver
* @param whichSideAmIOn
* @param i_packet250Type
* @param i_segmentSize
*/
protected SelectionPacket(Packet250Types i_packet250Type, Side whichSideAmIOn, int i_segmentSize)
{
super(i_packet250Type, whichSideAmIOn, i_segmentSize);
}
// derived classes should implement this interface so that callers wishing to create a new MultipartPacket (in response to an incoming packet)
// can pass this object to the packet handler, which will invoke it to create the SelectionPacket
public static class SelectionPacketCreator implements MultipartPacketCreator
{
public MultipartPacket createNewPacket(Packet250MultipartSegment packet)
{
return createReceiverPacket(packet);
}
}
}