    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}