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