Versions now have two flavours: the @Mod(version) which is the "programmatic version" and

is used for all version relationship calculation. The "display version" as sourced from
mcmod.info is used for display purposes only and can be literally anything. Note: they fall back
to one another when they're missing, and to "1.0" if both are absent.

Also, changed @Instance. Now, you can inject *other* mods using @Instance as long as you depend
on them as a "before" or "dependency" relationship. Classes containing @Instance will only be
loaded if the Mod the @Instance refers is present. So you don't have to worry about runtime class
resolution.
This commit is contained in:
Christian committed 2012-08-26 10:45:00 -04:00
1 parent 501009c11f
commit 8bef512803
10 files changed
+122 -36

No files matched your search

+1 -1
View File
@@ -123,7 +123,7 @@ public class GuiModList extends GuiScreen
this.field_73886_k.func_78261_a(selectedMod.getMetadata().name, offset, shifty, 0xFFFFFF);
shifty += 12;
shifty = drawLine(String.format("Version: %s (%s)", selectedMod.getMetadata().version, selectedMod.getVersion()), offset, shifty);
shifty = drawLine(String.format("Version: %s (%s)", selectedMod.getDisplayVersion(), selectedMod.getVersion()), offset, shifty);
shifty = drawLine(String.format("Mod State: %s", Loader.instance().getModState(selectedMod)), offset, shifty);
if (!selectedMod.getMetadata().credits.isEmpty()) {
shifty = drawLine(String.format("Credits: %s", selectedMod.getMetadata().credits), offset, shifty);
@@ -74,13 +74,13 @@ public class GuiSlotModList extends GuiScrollingList
if (Loader.instance().getModState(mc)==ModState.DISABLED)
{
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 10), this.left + 3 , var3 + 2, 0xFF2222);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getVersion(), listWidth - 10), this.left + 3 , var3 + 12, 0xFF2222);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getDisplayVersion(), listWidth - 10), this.left + 3 , var3 + 12, 0xFF2222);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a("DISABLED", listWidth - 10), this.left + 3 , var3 + 22, 0xFF2222);
}
else
{
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 10), this.left + 3 , var3 + 2, 0xFFFFFF);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getVersion(), listWidth - 10), this.left + 3 , var3 + 12, 0xCCCCCC);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getDisplayVersion(), listWidth - 10), this.left + 3 , var3 + 12, 0xCCCCCC);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getMetadata() !=null ? mc.getMetadata().getChildModCountString() : "Metadata not found", listWidth - 10), this.left + 3 , var3 + 22, 0xCCCCCC);
}
}
@@ -126,4 +126,10 @@ public class DummyModContainer implements ModContainer
{
return false;
}
@Override
public String getDisplayVersion()
{
return md.version;
}
}
+90 -28
View File
@@ -16,11 +16,14 @@ import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import com.google.common.base.Function;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.ArrayListMultimap;
@@ -28,6 +31,7 @@ import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
@@ -35,6 +39,7 @@ import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.Mod.Metadata;
import cpw.mods.fml.common.discovery.ASMDataTable;
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
import cpw.mods.fml.common.event.FMLConstructionEvent;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
@@ -56,9 +61,7 @@ public class FMLModContainer implements ModContainer
private String className;
private Map<String, Object> descriptor;
private boolean enabled = true;
private List<ArtifactVersion> requirements;
private List<ArtifactVersion> dependencies;
private List<ArtifactVersion> dependants;
private String internalVersion;
private boolean overridesMetadata;
private EventBus eventBus;
private LoadController controller;
@@ -100,7 +103,7 @@ public class FMLModContainer implements ModContainer
@Override
public String getVersion()
{
return modMetadata.version;
return internalVersion;
}
@Override
@@ -146,10 +149,16 @@ public class FMLModContainer implements ModContainer
FMLLog.info("Mod %s is missing the required element 'name'. Substituting %s", getModId(), getModId());
modMetadata.name = getModId();
}
if (Strings.isNullOrEmpty(modMetadata.version))
internalVersion = (String) descriptor.get("version");
if (Strings.isNullOrEmpty(internalVersion) && !Strings.isNullOrEmpty(modMetadata.version))
{
FMLLog.warning("Mod %s is missing the required element 'version'. Substituting 1", getModId());
modMetadata.version = "1";
FMLLog.warning("Mod %s is missing the required element 'version'. Falling back to metadata version %s", getModId(), modMetadata.version);
modMetadata.version = internalVersion;
}
if (Strings.isNullOrEmpty(internalVersion))
{
FMLLog.warning("Mod %s is missing the required element 'version' and no fallback can be found. Substituting '1.0'.", getModId());
modMetadata.version = internalVersion = "1.0";
}
}
@@ -216,15 +225,6 @@ public class FMLModContainer implements ModContainer
{
Multimap<Class<? extends Annotation>,Object> anns = ArrayListMultimap.create();
for (Field f : clazz.getDeclaredFields())
{
for (Annotation a : f.getAnnotations())
{
f.setAccessible(true);
anns.put(a.annotationType(), f);
}
}
for (Method m : clazz.getDeclaredMethods())
{
for (Annotation a : m.getAnnotations())
@@ -248,20 +248,25 @@ public class FMLModContainer implements ModContainer
return anns;
}
private void processFieldAnnotations() throws Exception
private void processFieldAnnotations(ASMDataTable asmDataTable) throws Exception
{
// Instance annotation
for (Object o : annotations.get(Instance.class))
{
Field f = (Field) o;
f.set(modInstance, modInstance);
}
SetMultimap<String, ASMData> annotations = asmDataTable.getAnnotationsFor(this);
for (Object o : annotations.get(Metadata.class))
parseSimpleFieldAnnotation(annotations, Instance.class.getName(), new Function<ModContainer, Object>()
{
Field f = (Field) o;
f.set(modInstance, modMetadata);
}
public Object apply(ModContainer mc)
{
return mc.getMod();
}
});
parseSimpleFieldAnnotation(annotations, Metadata.class.getName(), new Function<ModContainer, Object>()
{
public Object apply(ModContainer mc)
{
return mc.getMetadata();
}
});
//TODO
// for (Object o : annotations.get(Block.class))
// {
@@ -270,6 +275,57 @@ public class FMLModContainer implements ModContainer
// }
}
private void parseSimpleFieldAnnotation(SetMultimap<String, ASMData> annotations, String annotationClassName, Function<ModContainer, Object> retreiver) throws IllegalAccessException
{
System.out.println(annotationClassName);
String[] annName = annotationClassName.split("\\.");
System.out.println(Arrays.toString(annName));
String annotationName = annName[annName.length - 1];
for (ASMData targets : annotations.get(annotationClassName))
{
String targetMod = (String) targets.getAnnotationInfo().get("value");
Field f = null;
Object injectedMod = null;
ModContainer mc = this;
boolean isStatic = false;
Class<?> clz = modInstance.getClass();
if (!Strings.isNullOrEmpty(targetMod))
{
mc = Loader.instance().getIndexedModList().get(targetMod);
}
if (mc != null)
{
try
{
clz = Class.forName(targets.getClassName(), true, Loader.instance().getModClassLoader());
f = clz.getDeclaredField(targets.getObjectName());
f.setAccessible(true);
isStatic = Modifier.isStatic(f.getModifiers());
injectedMod = retreiver.apply(mc);
}
catch (Exception e)
{
Throwables.propagateIfPossible(e);
FMLLog.log(Level.WARNING, e, "Attempting to load @%s in class %s for %s and failing", annotationName, targets.getClassName(), mc.getModId());
}
}
if (f != null)
{
Object target = null;
if (!isStatic)
{
target = modInstance;
if (!modInstance.getClass().equals(clz))
{
FMLLog.warning("Unable to inject @%s in non-static field %s.%s for %s as it is NOT the primary mod instance", annotationName, targets.getClassName(), targets.getObjectName(), mc.getModId());
continue;
}
}
f.set(target, injectedMod);
}
}
}
@Subscribe
public void constructMod(FMLConstructionEvent event)
{
@@ -285,7 +341,7 @@ public class FMLModContainer implements ModContainer
isNetworkMod = FMLNetworkHandler.instance().registerNetworkMod(this, clazz, event.getASMHarvestedData());
modInstance = clazz.newInstance();
ProxyInjector.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide());
processFieldAnnotations();
processFieldAnnotations(event.getASMHarvestedData());
}
catch (Throwable e)
{
@@ -337,4 +393,10 @@ public class FMLModContainer implements ModContainer
{
return isNetworkMod;
}
@Override
public String getDisplayVersion()
{
return modMetadata.version;
}
}
@@ -104,4 +104,10 @@ public class InjectedModContainer implements ModContainer
{
return true;
}
@Override
public String getDisplayVersion()
{
return wrappedContainer.getDisplayVersion();
}
}
@@ -150,4 +150,6 @@ public interface ModContainer
boolean isImmutable();
boolean isNetworkMod();
String getDisplayVersion();
}
@@ -446,7 +446,7 @@ public class ModLoaderModContainer implements ModContainer
@Override
public void bindMetadata(MetadataCollection mc)
{
Map<String, Object> dummyMetadata = ImmutableMap.<String,Object>builder().put("name", modId).put("version", "").build();
Map<String, Object> dummyMetadata = ImmutableMap.<String,Object>builder().put("name", modId).put("version", "1.0").build();
this.metadata = mc.getMetadataForId(modId, dummyMetadata);
Loader.instance().computeDependencies(sortingProperties, getRequirements(), getDependencies(), getDependants());
}
@@ -585,4 +585,10 @@ public class ModLoaderModContainer implements ModContainer
{
return this.isNetworkMod;
}
@Override
public String getDisplayVersion()
{
return metadata!=null ? metadata.version : getVersion();
}
}
@@ -1,10 +1,14 @@
package cpw.mods.mockmod;
import cpw.mods.fml.common.Mod.Instance;
import net.minecraft.src.Block;
import net.minecraft.src.Material;
public class MockBlock extends Block
{
@Instance("mod_testMod")
public static Object tstInstance;
public MockBlock(int id)
{
super(id,Material.field_76259_v);
@@ -18,7 +18,7 @@ import cpw.mods.fml.common.network.NetworkMod;
import cpw.mods.fml.common.network.Player;
import cpw.mods.fml.common.ModMetadata;
@Mod(modid="MockMod", name="Mock Mod",version="1.2.3", dependencies="before:mod_testMod", useMetadata=true)
@Mod(modid="MockMod", name="Mock Mod",version="1.2.3", dependencies="after:mod_testMod", useMetadata=true)
@NetworkMod(channels={"MockMod"},clientSideRequired=true,packetHandler=MockMod.PacketHandler.class)
public class MockMod
{
@@ -58,6 +58,6 @@ public class MockMod
@Init
public void init(FMLInitializationEvent evt)
{
System.out.printf("Hello from mockmod init : %s %s\n", myInstance, meta);
System.out.printf("Hello from mockmod init : %s %s %s\n", myInstance, meta, MockBlock.tstInstance);
}
}
@@ -19,7 +19,7 @@ import net.minecraft.client.Minecraft;
@NetworkMod(channels={"mod_TestMod"},clientSideRequired=true,packetHandler=mod_testMod.PacketHandler.class)
public class mod_testMod extends BaseMod {
@MLProp
public static int test = 0;
public static class PacketHandler implements IPacketHandler
@@ -116,6 +116,6 @@ public class mod_testMod extends BaseMod {
@Override
public String getPriorities()
{
return "after:MockMod";
return "before:MockMod";
}
}