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.NetworkManager; 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(NetworkManager 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, 3); 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 }