001 package cpw.mods.fml.common.discovery; 002 003 import java.io.File; 004 import java.io.FileFilter; 005 import java.io.FileInputStream; 006 import java.util.Arrays; 007 import java.util.List; 008 import java.util.logging.Level; 009 import java.util.regex.Matcher; 010 011 import com.google.common.base.Throwables; 012 import com.google.common.collect.Lists; 013 014 import cpw.mods.fml.common.FMLLog; 015 import cpw.mods.fml.common.LoaderException; 016 import cpw.mods.fml.common.MetadataCollection; 017 import cpw.mods.fml.common.ModContainer; 018 import cpw.mods.fml.common.ModContainerFactory; 019 import cpw.mods.fml.common.discovery.asm.ASMModParser; 020 021 public class DirectoryDiscoverer implements ITypeDiscoverer 022 { 023 private class ClassFilter implements FileFilter 024 { 025 @Override 026 public boolean accept(File file) 027 { 028 return (file.isFile() && classFile.matcher(file.getName()).find()) || file.isDirectory(); 029 } 030 } 031 032 private ASMDataTable table; 033 034 @Override 035 public List<ModContainer> discover(ModCandidate candidate, ASMDataTable table) 036 { 037 this.table = table; 038 List<ModContainer> found = Lists.newArrayList(); 039 FMLLog.fine("Examining directory %s for potential mods", candidate.getModContainer().getName()); 040 exploreFileSystem("", candidate.getModContainer(), found, candidate, null); 041 for (ModContainer mc : found) 042 { 043 table.addContainer(mc); 044 } 045 return found; 046 } 047 048 public void exploreFileSystem(String path, File modDir, List<ModContainer> harvestedMods, ModCandidate candidate, MetadataCollection mc) 049 { 050 if (path.length() == 0) 051 { 052 File metadata = new File(modDir, "mcmod.info"); 053 try 054 { 055 FileInputStream fis = new FileInputStream(metadata); 056 mc = MetadataCollection.from(fis,modDir.getName()); 057 fis.close(); 058 FMLLog.fine("Found an mcmod.info file in directory %s", modDir.getName()); 059 } 060 catch (Exception e) 061 { 062 mc = MetadataCollection.from(null,""); 063 FMLLog.fine("No mcmod.info file found in directory %s", modDir.getName()); 064 } 065 } 066 067 File[] content = modDir.listFiles(new ClassFilter()); 068 069 // Always sort our content 070 Arrays.sort(content); 071 for (File file : content) 072 { 073 if (file.isDirectory()) 074 { 075 FMLLog.finest("Recursing into package %s", path + file.getName()); 076 exploreFileSystem(path + file.getName() + ".", file, harvestedMods, candidate, mc); 077 continue; 078 } 079 Matcher match = classFile.matcher(file.getName()); 080 081 if (match.matches()) 082 { 083 ASMModParser modParser = null; 084 try 085 { 086 FileInputStream fis = new FileInputStream(file); 087 modParser = new ASMModParser(fis); 088 fis.close(); 089 } 090 catch (LoaderException e) 091 { 092 FMLLog.log(Level.SEVERE, e, "There was a problem reading the file %s - probably this is a corrupt file", file.getPath()); 093 throw e; 094 } 095 catch (Exception e) 096 { 097 Throwables.propagate(e); 098 } 099 100 modParser.validate(); 101 modParser.sendToTable(table, candidate); 102 ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer(), candidate); 103 if (container!=null) 104 { 105 harvestedMods.add(container); 106 container.bindMetadata(mc); 107 } 108 } 109 110 111 } 112 } 113 114 }