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 }