package fyresmodjam.handlers; import java.nio.charset.Charset; import java.util.ArrayList; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayer; public class BasicPacket implements IPacket { public static Class[] validClassArray = { Integer.class, Boolean.class, String.class, Character.class, Byte.class, Float.class, Double.class, int[].class, int[][].class }; public static ArrayList> validClasses = new ArrayList>(); static { for (Class c : validClassArray) { validClasses.add(c); } } public Object[] data = null; public byte type; public BasicPacket() { } public BasicPacket(int type) { if (type == 0 || NewPacketHandler.packetTypes[type] != null) { throw new RuntimeException("Packet slot " + type + " already in use."); } NewPacketHandler.packetTypes[type] = this; this.type = (byte) type; } public BasicPacket(BasicPacket packet, Object... data) { if (isValidPacketType(packet)) { type = packet.type; } else { throw new RuntimeException("Must supply valid packet type."); } Class[] classes = getExpectedClasses(); if (classes != null) { for (Class c : classes) { if (!validClasses.contains(c)) { throw new RuntimeException("Argument class not valid. (" + c + ")"); } } if (data == null || data.length != classes.length) { throw new RuntimeException("Wrong number of arguments provided."); } else { for (int i = 0; i < data.length; i++) { if (data[i].getClass() != classes[i]) { throw new RuntimeException("Wrong argument class provided. (" + data[i].getClass() + ", expected " + classes[i] + ")"); } } } } this.data = data; } private boolean isValidPacketType(BasicPacket packet) { boolean packetTypeInBounds = packet.type > 0 && packet.type < NewPacketHandler.packetTypes.length; boolean packetTypeMatches = packet == NewPacketHandler.packetTypes[packet.type]; return packetTypeInBounds && packetTypeMatches; } @Override public void readBytes(ByteBuf bytes) { type = bytes.readByte(); Class[] classes = getExpectedClasses(); if (classes != null) { data = new Object[classes.length]; for (int i = 0; i < classes.length; i++) { if (classes[i] == Integer.class) { data[i] = bytes.readInt(); } if (classes[i] == int[].class) { int[] array = new int[bytes.readInt()]; for (int i2 = 0; i2 < array.length; i2++) { array[i2] = bytes.readInt(); } data[i] = array; } if (classes[i] == int[][].class) { int[][] array = new int[bytes.readInt()][]; for (int i2 = 0; i2 < array.length; i2++) { array[i2] = new int[bytes.readInt()]; for (int i3 = 0; i3 < array[i2].length; i3++) { array[i2][i3] = bytes.readInt(); } } data[i] = array; } else if (classes[i] == Boolean.class) { data[i] = bytes.readBoolean(); } else if (classes[i] == String.class) { int length = bytes.readInt(); try { byte[] stringBytes = new byte[length]; bytes.readBytes(stringBytes); data[i] = new String(stringBytes, "UTF-8"); } catch (Exception e) { e.printStackTrace(); } } else if (classes[i] == Byte.class) { data[i] = bytes.readByte(); } else if (classes[i] == Float.class) { data[i] = bytes.readDouble(); } else if (classes[i] == Double.class) { data[i] = bytes.readFloat(); } else if (classes[i] == Character.class) { data[i] = bytes.readChar(); } } } } @Override public void writeBytes(ByteBuf bytes) { bytes.writeByte(type); if (data != null) { for (int i = 0; i < data.length; i++) { if (data[i] instanceof Integer) { bytes.writeInt((Integer) data[i]); } else if (data[i] instanceof int[]) { bytes.writeInt(((int[]) data[i]).length); for (int i2 = 0; i2 < ((int[]) data[i]).length; i2++) { bytes.writeInt(((int[]) data[i])[i2]); } } else if (data[i] instanceof int[][]) { int[][] values = (int[][]) data[i]; bytes.writeInt(values.length); for (int i2 = 0; i2 < values.length; i2++) { bytes.writeInt(values[i2].length); for (int i3 = 0; i3 < values[i2].length; i3++) { bytes.writeInt(values[i2][i3]); } } } else if (data[i] instanceof Boolean) { bytes.writeBoolean((Boolean) data[i]); } else if (data[i] instanceof String) { byte[] stringBytes = ((String) data[i]).getBytes(Charset.forName("UTF-8")); bytes.writeInt(stringBytes.length); bytes.writeBytes(stringBytes); } else if (data[i] instanceof Byte) { bytes.writeByte((Byte) data[i]); } else if (data[i] instanceof Float) { bytes.writeDouble((Double) data[i]); } else if (data[i] instanceof Double) { bytes.writeFloat((Float) data[i]); } else if (data[i] instanceof Character) { bytes.writeChar((Character) data[i]); } } } } @Override public void executeClient(EntityPlayer player) { if (NewPacketHandler.packetTypes[type] != this) { NewPacketHandler.packetTypes[type].executeClient(player); } } @Override public void executeServer(EntityPlayer player) { if (NewPacketHandler.packetTypes[type] != this) { NewPacketHandler.packetTypes[type].executeServer(player); } } @Override public void executeBoth(EntityPlayer player) { if (NewPacketHandler.packetTypes[type] != this) { NewPacketHandler.packetTypes[type].executeBoth(player); } } public Class[] getExpectedClasses() { if (NewPacketHandler.packetTypes[type] != this) { return NewPacketHandler.packetTypes[type].getExpectedClasses(); } else { return null; } } public void sendToPlayer(EntityPlayer player, Object... data) { NewPacketHandler.sendPacketToPlayer(new BasicPacket(this, data), player); } public void sendToAllPlayers(Object... data) { NewPacketHandler.sendPacketToAllPlayers(new BasicPacket(this, data)); } public void sendToServer(Object... data) { NewPacketHandler.sendPacketToServer(new BasicPacket(this, data)); } }