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