001 package cpw.mods.fml.common.discovery; 002 003 import java.util.Collections; 004 import java.util.List; 005 import java.util.logging.Level; 006 import java.util.regex.Matcher; 007 import java.util.zip.ZipEntry; 008 import java.util.zip.ZipFile; 009 010 import com.google.common.collect.Lists; 011 012 import cpw.mods.fml.common.FMLLog; 013 import cpw.mods.fml.common.LoaderException; 014 import cpw.mods.fml.common.MetadataCollection; 015 import cpw.mods.fml.common.ModContainer; 016 import cpw.mods.fml.common.ModContainerFactory; 017 import cpw.mods.fml.common.discovery.asm.ASMModParser; 018 019 public class JarDiscoverer implements ITypeDiscoverer 020 { 021 @Override 022 public List<ModContainer> discover(ModCandidate candidate, ASMDataTable table) 023 { 024 List<ModContainer> foundMods = Lists.newArrayList(); 025 FMLLog.fine("Examining file %s for potential mods", candidate.getModContainer().getName()); 026 ZipFile jar = null; 027 try 028 { 029 jar = new ZipFile(candidate.getModContainer()); 030 031 ZipEntry modInfo = jar.getEntry("mcmod.info"); 032 MetadataCollection mc = null; 033 if (modInfo != null) 034 { 035 FMLLog.finer("Located mcmod.info file in file %s", candidate.getModContainer().getName()); 036 mc = MetadataCollection.from(jar.getInputStream(modInfo), candidate.getModContainer().getName()); 037 } 038 else 039 { 040 FMLLog.fine("The mod container %s appears to be missing an mcmod.info file", candidate.getModContainer().getName()); 041 mc = MetadataCollection.from(null, ""); 042 } 043 for (ZipEntry ze : Collections.list(jar.entries())) 044 { 045 Matcher match = classFile.matcher(ze.getName()); 046 if (match.matches()) 047 { 048 ASMModParser modParser; 049 try 050 { 051 modParser = new ASMModParser(jar.getInputStream(ze)); 052 } 053 catch (LoaderException e) 054 { 055 FMLLog.log(Level.SEVERE, e, "There was a problem reading the entry %s in the jar %s - probably a corrupt zip", ze.getName(), candidate.getModContainer().getPath()); 056 jar.close(); 057 throw e; 058 } 059 modParser.validate(); 060 modParser.sendToTable(table, candidate); 061 ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer(), candidate); 062 if (container!=null) 063 { 064 table.addContainer(container); 065 foundMods.add(container); 066 container.bindMetadata(mc); 067 } 068 } 069 } 070 } 071 catch (Exception e) 072 { 073 FMLLog.log(Level.WARNING, e, "Zip file %s failed to read properly, it will be ignored", candidate.getModContainer().getName()); 074 } 075 finally 076 { 077 if (jar != null) 078 { 079 try 080 { 081 jar.close(); 082 } 083 catch (Exception e) 084 { 085 } 086 } 087 } 088 return foundMods; 089 } 090 091 }