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.INetworkManager;
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(INetworkManager network, FMLNetworkHandler handler, NetHandler netHandler, String userName);
095        {
096            // TODO Auto-generated method stub
097    
098        }
099    }