    001    package cpw.mods.fml.common.network;
    002
    003    import static cpw.mods.fml.common.network.FMLPacket.Type.MOD_IDENTIFIERS;
    004    import static cpw.mods.fml.common.network.FMLPacket.Type.MOD_LIST_RESPONSE;
    005    import static cpw.mods.fml.common.network.FMLPacket.Type.MOD_MISSING;
    006
    007    import java.util.List;
    008    import java.util.Map;
    009    import java.util.Map.Entry;
    010    import java.util.logging.Logger;
    011
    012    import net.minecraft.src.NetHandler;
    013    import net.minecraft.src.NetLoginHandler;
    014    import net.minecraft.src.INetworkManager;
    015    import net.minecraft.src.Packet250CustomPayload;
    016
    017    import com.google.common.collect.Lists;
    018    import com.google.common.collect.Maps;
    019    import com.google.common.io.ByteArrayDataInput;
    020    import com.google.common.io.ByteArrayDataOutput;
    021    import com.google.common.io.ByteStreams;
    022
    023    import cpw.mods.fml.common.FMLLog;
    024    import cpw.mods.fml.common.Loader;
    025    import cpw.mods.fml.common.ModContainer;
    026
    027    public class ModListResponsePacket extends FMLPacket
    028    {
    029        private Map<String,String> modVersions;
    030        private List<String> missingMods;
    031
    032        public ModListResponsePacket()
    033        {
    034            super(MOD_LIST_RESPONSE);
    035        }
    036
    037        @Override
    038        public byte[] generatePacket(Object... data)
    039        {
    040            Map<String,String> modVersions = (Map<String, String>) data[0];
    041            List<String> missingMods = (List<String>) data[1];
    042            ByteArrayDataOutput dat = ByteStreams.newDataOutput();
    043            dat.writeInt(modVersions.size());
    044            for (Entry<String, String> version : modVersions.entrySet())
    045            {
    046                dat.writeUTF(version.getKey());
    047                dat.writeUTF(version.getValue());
    048            }
    049            dat.writeInt(missingMods.size());
    050            for (String missing : missingMods)
    051            {
    052                dat.writeUTF(missing);
    053            }
    054            return dat.toByteArray();
    055        }
    056
    057        @Override
    058        public FMLPacket consumePacket(byte[] data)
    059        {
    060            ByteArrayDataInput dat = ByteStreams.newDataInput(data);
    061            int versionListSize = dat.readInt();
    062            modVersions = Maps.newHashMapWithExpectedSize(versionListSize);
    063            for (int i = 0; i < versionListSize; i++)
    064            {
    065                String modName = dat.readUTF();
    066                String modVersion = dat.readUTF();
    067                modVersions.put(modName, modVersion);
    068            }
    069
    070            int missingModSize = dat.readInt();
    071            missingMods = Lists.newArrayListWithExpectedSize(missingModSize);
    072
    073            for (int i = 0; i < missingModSize; i++)
    074            {
    075                missingMods.add(dat.readUTF());
    076            }
    077            return this;
    078        }
    079
    080        @Override
    081        public void execute(INetworkManager network, FMLNetworkHandler handler, NetHandler netHandler, String userName)
    082        {
    083            Map<String, ModContainer> indexedModList = Maps.newHashMap(Loader.instance().getIndexedModList());
    084            List<String> missingClientMods = Lists.newArrayList();
    085            List<String> versionIncorrectMods = Lists.newArrayList();
    086
    087            for (String m : missingMods)
    088            {
    089                ModContainer mc = indexedModList.get(m);
    090                NetworkModHandler networkMod = handler.findNetworkModHandler(mc);
    091                if (networkMod.requiresClientSide())
    092                {
    093                    missingClientMods.add(m);
    094                }
    095            }
    096
    097            for (Entry<String,String> modVersion : modVersions.entrySet())
    098            {
    099                ModContainer mc = indexedModList.get(modVersion.getKey());
    100                NetworkModHandler networkMod = handler.findNetworkModHandler(mc);
    101                if (!networkMod.acceptVersion(modVersion.getValue()))
    102                {
    103                    versionIncorrectMods.add(modVersion.getKey());
    104                }
    105            }
    106
    107            Packet250CustomPayload pkt = new Packet250CustomPayload();
    108            pkt.channel = "FML";
    109            if (missingClientMods.size()>0 || versionIncorrectMods.size() > 0)
    110            {
    111                pkt.data = FMLPacket.makePacket(MOD_MISSING, missingClientMods, versionIncorrectMods);
    112                Logger.getLogger("Minecraft").info(String.format("User %s connection failed: missing %s, bad versions %s", userName, missingClientMods, versionIncorrectMods));
    113                FMLLog.info("User %s connection failed: missing %s, bad versions %s", userName, missingClientMods, versionIncorrectMods);
    114                // Mark this as bad
    115                FMLNetworkHandler.setHandlerState((NetLoginHandler) netHandler, FMLNetworkHandler.MISSING_MODS_OR_VERSIONS);
    116            }
    117            else
    118            {
    119                pkt.data = FMLPacket.makePacket(MOD_IDENTIFIERS, netHandler);
    120                Logger.getLogger("Minecraft").info(String.format("User %s connecting with mods %s", userName, modVersions.keySet()));
    121                FMLLog.info("User %s connecting with mods %s", userName, modVersions.keySet());
    122            }
    123
    124            pkt.length = pkt.data.length;
    125            network.addToSendQueue(pkt);
    126            // reset the continuation flag - we have completed extra negotiation and the login should complete now
    127            NetLoginHandler.func_72531_a((NetLoginHandler) netHandler, true);
    128        }
    129
    130    }