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