    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    }