001    package cpw.mods.fml.common.network;
002    
003    import java.io.IOException;
004    import java.util.BitSet;
005    import java.util.Set;
006    import java.util.logging.Level;
007    
008    import net.minecraft.nbt.*;
009    import net.minecraft.network.INetworkManager;
010    import net.minecraft.network.packet.NetHandler;
011    
012    import com.google.common.collect.MapDifference;
013    import com.google.common.io.ByteArrayDataInput;
014    import com.google.common.io.ByteStreams;
015    import com.google.common.primitives.Bytes;
016    import com.google.common.primitives.Ints;
017    import com.google.common.primitives.UnsignedBytes;
018    
019    import cpw.mods.fml.client.FMLClientHandler;
020    import cpw.mods.fml.common.FMLCommonHandler;
021    import cpw.mods.fml.common.FMLLog;
022    import cpw.mods.fml.common.registry.GameData;
023    import cpw.mods.fml.common.registry.GameRegistry;
024    import cpw.mods.fml.common.registry.ItemData;
025    import static cpw.mods.fml.common.network.FMLPacket.Type.MOD_IDMAP;
026    
027    public class ModIdMapPacket extends FMLPacket {
028        private byte[][] partials;
029    
030        public ModIdMapPacket()
031        {
032            super(MOD_IDMAP);
033        }
034    
035        @Override
036        public byte[] generatePacket(Object... data)
037        {
038            NBTTagList completeList = (NBTTagList) data[0];
039            NBTTagCompound wrap = new NBTTagCompound();
040            wrap.setTag("List", completeList);
041            try
042            {
043                return CompressedStreamTools.compress(wrap);
044            }
045            catch (Exception e)
046            {
047                FMLLog.log(Level.SEVERE, e, "A critical error writing the id map");
048                throw new FMLNetworkException(e);
049            }
050        }
051    
052        @Override
053        public FMLPacket consumePacket(byte[] data)
054        {
055            ByteArrayDataInput bdi = ByteStreams.newDataInput(data);
056            int chunkIdx = UnsignedBytes.toInt(bdi.readByte());
057            int chunkTotal = UnsignedBytes.toInt(bdi.readByte());
058            int chunkLength = bdi.readInt();
059            if (partials == null)
060            {
061                partials = new byte[chunkTotal][];
062            }
063            partials[chunkIdx] = new byte[chunkLength];
064            bdi.readFully(partials[chunkIdx]);
065            for (int i = 0; i < partials.length; i++)
066            {
067                if (partials[i] == null)
068                {
069                    return null;
070                }
071            }
072            return this;
073        }
074    
075        @Override
076        public void execute(INetworkManager network, FMLNetworkHandler handler, NetHandler netHandler, String userName)
077        {
078            byte[] allData = Bytes.concat(partials);
079            GameData.initializeServerGate(1);
080            try
081            {
082                NBTTagCompound serverList = CompressedStreamTools.decompress(allData);
083                NBTTagList list = serverList.getTagList("List");
084                Set<ItemData> itemData = GameData.buildWorldItemData(list);
085                GameData.validateWorldSave(itemData);
086                MapDifference<Integer, ItemData> serverDifference = GameData.gateWorldLoadingForValidation();
087                if (serverDifference!=null)
088                {
089                    FMLCommonHandler.instance().disconnectIDMismatch(serverDifference, netHandler, network);
090    
091                }
092            }
093            catch (IOException e)
094            {
095            }
096        }
097    
098    }