    001    package cpw.mods.fml.common.network;
    002
    003    import java.util.Arrays;
    004    import java.util.logging.Level;
    005
    006    import net.minecraft.src.NetHandler;
    007    import net.minecraft.src.NetworkManager;
    008
    009    import com.google.common.base.Throwables;
    010    import com.google.common.primitives.Bytes;
    011    import com.google.common.primitives.UnsignedBytes;
    012
    013    import cpw.mods.fml.common.FMLLog;
    014
    015    public abstract class FMLPacket
    016    {
    017        enum Type
    018        {
    019            /**
    020             * Opening salutation from the server to the client -> request all mods from the client
    021             */
    022            MOD_LIST_REQUEST(ModListRequestPacket.class),
    023            /**
    024             * The client responds with the list of mods and versions it has. This is verified by the server.
    025             */
    026            MOD_LIST_RESPONSE(ModListResponsePacket.class),
    027            /**
    028             * At which point the server tells the client the mod identifiers for this session.
    029             */
    030            MOD_IDENTIFIERS(ModIdentifiersPacket.class),
    031            /**
    032             * Or, if there is missing stuff, the server tells the client what's missing and drops the connection.
    033             */
    034            MOD_MISSING(ModMissingPacket.class),
    035            /**
    036             * Open a GUI on the client from the server
    037             */
    038            GUIOPEN(OpenGuiPacket.class),
    039            /**
    040             * Spawn an entity on the client from the server
    041             */
    042            ENTITYSPAWN(EntitySpawnPacket.class),
    043            /**
    044             * Fixes entity location data after spawning
    045             */
    046            ENTITYSPAWNADJUSTMENT(EntitySpawnAdjustmentPacket.class);
    047
    048
    049            private Class<? extends FMLPacket> packetType;
    050
    051            private Type(Class<? extends FMLPacket> clazz)
    052            {
    053                this.packetType = clazz;
    054            }
    055
    056            FMLPacket make()
    057            {
    058                try
    059                {
    060                    return this.packetType.newInstance();
    061                }
    062                catch (Exception e)
    063                {
    064                    Throwables.propagateIfPossible(e);
    065                    FMLLog.log(Level.SEVERE, e, "A bizarre critical error occured during packet encoding");
    066                    throw new FMLNetworkException(e);
    067                }
    068            }
    069        }
    070
    071        private Type type;
    072
    073        public static byte[] makePacket(Type type, Object... data)
    074        {
    075            byte[] packetData = type.make().generatePacket(data);
    076            return Bytes.concat(new byte[] { UnsignedBytes.checkedCast(type.ordinal()) }, packetData );
    077        }
    078
    079        public static FMLPacket readPacket(byte[] payload)
    080        {
    081            int type = UnsignedBytes.toInt(payload[0]);
    082            return Type.values()[type].make().consumePacket(Arrays.copyOfRange(payload, 1, payload.length));
    083        }
    084
    085        public FMLPacket(Type type)
    086        {
    087            this.type = type;
    088        }
    089
    090        public abstract byte[] generatePacket(Object... data);
    091
    092        public abstract FMLPacket consumePacket(byte[] data);
    093
    094        public abstract void execute(NetworkManager network, FMLNetworkHandler handler, NetHandler netHandler, String userName);
    095        {
    096            // TODO Auto-generated method stub
    097
    098        }
    099    }