001package cpw.mods.fml.common.network;
002
003import java.io.IOException;
004import java.util.BitSet;
005import java.util.Set;
006import java.util.logging.Level;
007
008import net.minecraft.nbt.*;
009import net.minecraft.network.INetworkManager;
010import net.minecraft.network.packet.NetHandler;
011
012import com.google.common.collect.MapDifference;
013import com.google.common.io.ByteArrayDataInput;
014import com.google.common.io.ByteStreams;
015import com.google.common.primitives.Bytes;
016import com.google.common.primitives.Ints;
017import com.google.common.primitives.UnsignedBytes;
018
019import cpw.mods.fml.client.FMLClientHandler;
020import cpw.mods.fml.common.FMLCommonHandler;
021import cpw.mods.fml.common.FMLLog;
022import cpw.mods.fml.common.registry.GameData;
023import cpw.mods.fml.common.registry.GameRegistry;
024import cpw.mods.fml.common.registry.ItemData;
025import static cpw.mods.fml.common.network.FMLPacket.Type.MOD_IDMAP;
026
027public 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}