001/* 002 * Forge Mod Loader 003 * Copyright (c) 2012-2013 cpw. 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser Public License v2.1 006 * which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 008 * 009 * Contributors: 010 * cpw - implementation 011 */ 012 013package cpw.mods.fml.common; 014 015import java.io.File; 016import java.util.regex.Pattern; 017 018import org.objectweb.asm.Type; 019 020import cpw.mods.fml.common.discovery.ModCandidate; 021import cpw.mods.fml.common.discovery.asm.ASMModParser; 022import cpw.mods.fml.common.discovery.asm.ModAnnotation; 023import cpw.mods.fml.common.modloader.ModLoaderModContainer; 024 025public class ModContainerFactory 026{ 027 private static Pattern modClass = Pattern.compile(".*(\\.|)(mod\\_[^\\s$]+)$"); 028 private static ModContainerFactory INSTANCE = new ModContainerFactory(); 029 public static ModContainerFactory instance() { 030 return INSTANCE; 031 } 032 public ModContainer build(ASMModParser modParser, File modSource, ModCandidate container) 033 { 034 String className = modParser.getASMType().getClassName(); 035 if (modParser.isBaseMod(container.getRememberedBaseMods()) && modClass.matcher(className).find()) 036 { 037 FMLLog.fine("Identified a BaseMod type mod %s", className); 038 return new ModLoaderModContainer(className, modSource, modParser.getBaseModProperties()); 039 } 040 else if (modClass.matcher(className).find()) 041 { 042 FMLLog.fine("Identified a class %s following modloader naming convention but not directly a BaseMod or currently seen subclass", className); 043 container.rememberModCandidateType(modParser); 044 } 045 else if (modParser.isBaseMod(container.getRememberedBaseMods())) 046 { 047 FMLLog.fine("Found a basemod %s of non-standard naming format", className); 048 container.rememberBaseModType(className); 049 } 050 051 // We warn if it's not a basemod instance -- compatibility requires it to be in net.minecraft.src *sigh* 052 if (className.startsWith("net.minecraft.src.") && container.isClasspath() && !container.isMinecraftJar()) 053 { 054 FMLLog.severe("FML has detected a mod that is using a package name based on 'net.minecraft.src' : %s. This is generally a severe programming error. " 055 + " There should be no mod code in the minecraft namespace. MOVE YOUR MOD! If you're in eclipse, select your source code and 'refactor' it into " 056 + "a new package. Go on. DO IT NOW!",className); 057 } 058 059 for (ModAnnotation ann : modParser.getAnnotations()) 060 { 061 if (ann.getASMType().equals(Type.getType(Mod.class))) 062 { 063 FMLLog.fine("Identified an FMLMod type mod %s", className); 064 return new FMLModContainer(className, modSource, ann.getValues()); 065 } 066 } 067 068 return null; 069 } 070}