| 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) |
| { |
| |
| } |
| } |