blob: 311f293370c51ae331f110c30aa78b1db052fa07 [file] [log] [blame] [raw]
package universalelectricity.prefab.network;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import universalelectricity.core.vector.Vector3;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import cpw.mods.fml.common.network.IPacketHandler;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;
/**
* This class is used for sending and receiving packets between the server and the client. You can
* directly use this by registering this packet manager with NetworkMod. Example:
*
* @NetworkMod(channels = { "BasicComponents" }, clientSideRequired = true, serverSideRequired =
* false, packetHandler = PacketManager.class)
*
* Check out {@link #BasicComponents} for better reference.
*
* @author Calclavia
*/
public class PacketManager implements IPacketHandler, IPacketReceiver
{
public enum PacketType
{
UNSPECIFIED, TILEENTITY;
public static PacketType get(int id)
{
if (id >= 0 && id < PacketType.values().length)
{
return PacketType.values()[id];
}
return UNSPECIFIED;
}
}
/**
* Writes a compressed NBTTagCompound to the OutputStream
*/
public static void writeNBTTagCompound(NBTTagCompound tag, DataOutputStream dataStream) throws IOException
{
if (tag == null)
{
dataStream.writeShort(-1);
}
else
{
byte[] var2 = CompressedStreamTools.compress(tag);
dataStream.writeShort((short) var2.length);
dataStream.write(var2);
}
}
public static void writeNBTTagCompound(NBTTagCompound tag, ByteArrayDataOutput dataStream) throws IOException
{
if (tag == null)
{
dataStream.writeShort(-1);
}
else
{
byte[] var2 = CompressedStreamTools.compress(tag);
dataStream.writeShort((short) var2.length);
dataStream.write(var2);
}
}
/**
* Reads a compressed NBTTagCompount in a ByteStream.
*/
public static NBTTagCompound readNBTTagCompound(DataInputStream dataStream) throws IOException
{
short var1 = dataStream.readShort();
if (var1 < 0)
{
return null;
}
else
{
byte[] var2 = new byte[var1];
dataStream.readFully(var2);
return CompressedStreamTools.decompress(var2);
}
}
public static NBTTagCompound readNBTTagCompound(ByteArrayDataInput dataStream) throws IOException
{
short var1 = dataStream.readShort();
if (var1 < 0)
{
return null;
}
else
{
byte[] var2 = new byte[var1];
dataStream.readFully(var2);
return CompressedStreamTools.decompress(var2);
}
}
@SuppressWarnings("resource")
public static Packet getPacketWithID(String channelName, int id, Object... sendData)
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
try
{
data.writeInt(id);
data = encodeDataStream(data, sendData);
Packet250CustomPayload packet = new Packet250CustomPayload();
packet.channel = channelName;
packet.data = bytes.toByteArray();
packet.length = packet.data.length;
return packet;
}
catch (IOException e)
{
System.out.println("Failed to create packet.");
e.printStackTrace();
}
return null;
}
public static Packet getPacket(String channelName, Object... sendData)
{
return getPacketWithID(channelName, PacketType.UNSPECIFIED.ordinal(), sendData);
}
/**
* Gets a packet for the tile entity.
*
* @return
*/
@SuppressWarnings("resource")
public static Packet getPacket(String channelName, TileEntity sender, Object... sendData)
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
try
{
data.writeInt(PacketType.TILEENTITY.ordinal());
data.writeInt(sender.xCoord);
data.writeInt(sender.yCoord);
data.writeInt(sender.zCoord);
data = encodeDataStream(data, sendData);
Packet250CustomPayload packet = new Packet250CustomPayload();
packet.channel = channelName;
packet.data = bytes.toByteArray();
packet.length = packet.data.length;
return packet;
}
catch (IOException e)
{
System.out.println("Failed to create packet.");
e.printStackTrace();
}
return null;
}
/**
* Sends packets to clients around a specific coordinate. A wrapper using Vector3. See
* {@PacketDispatcher} for detailed information.
*/
public static void sendPacketToClients(Packet packet, World worldObj, Vector3 position, double range)
{
try
{
PacketDispatcher.sendPacketToAllAround(position.x, position.y, position.z, range, worldObj.provider.dimensionId, packet);
}
catch (Exception e)
{
System.out.println("Sending packet to client failed.");
e.printStackTrace();
}
}
/**
* Sends a packet to all the clients on this server.
*/
public static void sendPacketToClients(Packet packet, World worldObj)
{
try
{
PacketDispatcher.sendPacketToAllInDimension(packet, worldObj.provider.dimensionId);
}
catch (Exception e)
{
System.out.println("Sending packet to client failed.");
e.printStackTrace();
}
}
public static void sendPacketToClients(Packet packet)
{
try
{
PacketDispatcher.sendPacketToAllPlayers(packet);
}
catch (Exception e)
{
System.out.println("Sending packet to client failed.");
e.printStackTrace();
}
}
public static DataOutputStream encodeDataStream(DataOutputStream data, Object... sendData)
{
try
{
for (Object dataValue : sendData)
{
if (dataValue instanceof Integer)
{
data.writeInt((Integer) dataValue);
}
else if (dataValue instanceof Float)
{
data.writeFloat((Float) dataValue);
}
else if (dataValue instanceof Double)
{
data.writeDouble((Double) dataValue);
}
else if (dataValue instanceof Byte)
{
data.writeByte((Byte) dataValue);
}
else if (dataValue instanceof Boolean)
{
data.writeBoolean((Boolean) dataValue);
}
else if (dataValue instanceof String)
{
data.writeUTF((String) dataValue);
}
else if (dataValue instanceof Short)
{
data.writeShort((Short) dataValue);
}
else if (dataValue instanceof Long)
{
data.writeLong((Long) dataValue);
}
else if (dataValue instanceof NBTTagCompound)
{
writeNBTTagCompound((NBTTagCompound) dataValue, data);
}
}
return data;
}
catch (IOException e)
{
System.out.println("Packet data encoding failed.");
e.printStackTrace();
}
return data;
}
@Override
public void onPacketData(INetworkManager network, Packet250CustomPayload packet, Player player)
{
try
{
ByteArrayDataInput data = ByteStreams.newDataInput(packet.data);
int packetTypeID = data.readInt();
PacketType packetType = PacketType.get(packetTypeID);
if (packetType == PacketType.TILEENTITY)
{
int x = data.readInt();
int y = data.readInt();
int z = data.readInt();
World world = ((EntityPlayer) player).worldObj;
if (world != null)
{
TileEntity tileEntity = world.getBlockTileEntity(x, y, z);
if (tileEntity != null)
{
if (tileEntity instanceof IPacketReceiver)
{
((IPacketReceiver) tileEntity).handlePacketData(network, packetTypeID, packet, ((EntityPlayer) player), data);
}
}
}
}
else
{
this.handlePacketData(network, packetTypeID, packet, ((EntityPlayer) player), data);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
@Override
public void handlePacketData(INetworkManager network, int packetType, Packet250CustomPayload packet, EntityPlayer player, ByteArrayDataInput dataStream)
{
}
}