Search in sources :

Example 11 with ArtifactVersion

use of net.minecraftforge.fml.common.versioning.ArtifactVersion in project MinecraftForge by MinecraftForge.

the class FMLModContainer method bindMetadata.

@Override
public void bindMetadata(MetadataCollection mc) {
    modMetadata = mc.getMetadataForId(getModId(), descriptor);
    if (descriptor.containsKey("useMetadata")) {
        overridesMetadata = !((Boolean) descriptor.get("useMetadata"));
    }
    if (overridesMetadata || !modMetadata.useDependencyInformation) {
        Set<ArtifactVersion> requirements = Sets.newHashSet();
        List<ArtifactVersion> dependencies = Lists.newArrayList();
        List<ArtifactVersion> dependants = Lists.newArrayList();
        annotationDependencies = (String) descriptor.get("dependencies");
        Loader.instance().computeDependencies(annotationDependencies, requirements, dependencies, dependants);
        dependants.addAll(Loader.instance().getInjectedBefore(getModId()));
        dependencies.addAll(Loader.instance().getInjectedAfter(getModId()));
        modMetadata.requiredMods = requirements;
        modMetadata.dependencies = dependencies;
        modMetadata.dependants = dependants;
        FMLLog.log(getModId(), Level.TRACE, "Parsed dependency info : %s %s %s", requirements, dependencies, dependants);
    } else {
        FMLLog.log(getModId(), Level.TRACE, "Using mcmod dependency info : %s %s %s", modMetadata.requiredMods, modMetadata.dependencies, modMetadata.dependants);
    }
    if (Strings.isNullOrEmpty(modMetadata.name)) {
        FMLLog.log(getModId(), Level.INFO, "Mod %s is missing the required element 'name'. Substituting %s", getModId(), getModId());
        modMetadata.name = getModId();
    }
    internalVersion = (String) descriptor.get("version");
    if (Strings.isNullOrEmpty(internalVersion)) {
        Properties versionProps = searchForVersionProperties();
        if (versionProps != null) {
            internalVersion = versionProps.getProperty(getModId() + ".version");
            FMLLog.log(getModId(), Level.DEBUG, "Found version %s for mod %s in version.properties, using", internalVersion, getModId());
        }
    }
    if (Strings.isNullOrEmpty(internalVersion) && !Strings.isNullOrEmpty(modMetadata.version)) {
        FMLLog.log(getModId(), Level.WARN, "Mod %s is missing the required element 'version' and a version.properties file could not be found. Falling back to metadata version %s", getModId(), modMetadata.version);
        internalVersion = modMetadata.version;
    }
    if (Strings.isNullOrEmpty(internalVersion)) {
        FMLLog.log(getModId(), Level.WARN, "Mod %s is missing the required element 'version' and no fallback can be found. Substituting '1.0'.", getModId());
        modMetadata.version = internalVersion = "1.0";
    }
    String mcVersionString = (String) descriptor.get("acceptedMinecraftVersions");
    // MC 1.8.8 and 1.8.9 is forward SRG compatible so accept these versions by default.
    if ("[1.8.8]".equals(mcVersionString))
        mcVersionString = "[1.8.8,1.8.9]";
    if ("[1.9.4]".equals(mcVersionString) || "[1.9,1.9.4]".equals(mcVersionString) || "[1.9.4,1.10)".equals(mcVersionString) || "[1.10]".equals(mcVersionString))
        mcVersionString = "[1.9.4,1.10.2]";
    if ("[1.11]".equals(mcVersionString))
        mcVersionString = "[1.11,1.11.2]";
    if (!Strings.isNullOrEmpty(mcVersionString)) {
        minecraftAccepted = VersionParser.parseRange(mcVersionString);
    } else {
        minecraftAccepted = Loader.instance().getMinecraftModContainer().getStaticVersionRange();
    }
    String jsonURL = (String) descriptor.get("updateJSON");
    if (!Strings.isNullOrEmpty(jsonURL)) {
        try {
            this.updateJSONUrl = new URL(jsonURL);
        } catch (MalformedURLException e) {
            FMLLog.log(getModId(), Level.DEBUG, "Specified json URL invalid: %s", jsonURL);
        }
    }
}
Also used : MalformedURLException(java.net.MalformedURLException) ArtifactVersion(net.minecraftforge.fml.common.versioning.ArtifactVersion) DefaultArtifactVersion(net.minecraftforge.fml.common.versioning.DefaultArtifactVersion) Properties(java.util.Properties) URL(java.net.URL)

Example 12 with ArtifactVersion

use of net.minecraftforge.fml.common.versioning.ArtifactVersion in project MinecraftForge by MinecraftForge.

the class Loader method sortModList.

/**
     * Sort the mods into a sorted list, using dependency information from the
     * containers. The sorting is performed using a {@link TopologicalSort}
     * based on the pre- and post- dependency information provided by the mods.
     */
private void sortModList() {
    FMLLog.finer("Verifying mod requirements are satisfied");
    List<WrongMinecraftVersionException> wrongMinecraftExceptions = new ArrayList<WrongMinecraftVersionException>();
    List<MissingModsException> missingModsExceptions = new ArrayList<MissingModsException>();
    try {
        BiMap<String, ArtifactVersion> modVersions = HashBiMap.create();
        for (ModContainer mod : Iterables.concat(getActiveModList(), ModAPIManager.INSTANCE.getAPIList())) {
            modVersions.put(mod.getModId(), mod.getProcessedVersion());
        }
        ArrayListMultimap<String, String> reqList = ArrayListMultimap.create();
        for (ModContainer mod : getActiveModList()) {
            if (!mod.acceptableMinecraftVersionRange().containsVersion(minecraft.getProcessedVersion())) {
                FMLLog.severe("The mod %s does not wish to run in Minecraft version %s. You will have to remove it to play.", mod.getModId(), getMCVersionString());
                WrongMinecraftVersionException ret = new WrongMinecraftVersionException(mod, getMCVersionString());
                FMLLog.severe(ret.getMessage());
                wrongMinecraftExceptions.add(ret);
                continue;
            }
            Map<String, ArtifactVersion> names = Maps.uniqueIndex(mod.getRequirements(), new ArtifactVersionNameFunction());
            Set<ArtifactVersion> versionMissingMods = Sets.newHashSet();
            Set<String> missingMods = Sets.difference(names.keySet(), modVersions.keySet());
            if (!missingMods.isEmpty()) {
                FMLLog.severe("The mod %s (%s) requires mods %s to be available", mod.getModId(), mod.getName(), missingMods);
                for (String modid : missingMods) {
                    versionMissingMods.add(names.get(modid));
                }
                MissingModsException ret = new MissingModsException(versionMissingMods, mod.getModId(), mod.getName());
                FMLLog.severe(ret.getMessage());
                missingModsExceptions.add(ret);
                continue;
            }
            reqList.putAll(mod.getModId(), names.keySet());
            ImmutableList<ArtifactVersion> allDeps = ImmutableList.<ArtifactVersion>builder().addAll(mod.getDependants()).addAll(mod.getDependencies()).build();
            for (ArtifactVersion v : allDeps) {
                if (modVersions.containsKey(v.getLabel())) {
                    if (!v.containsVersion(modVersions.get(v.getLabel()))) {
                        versionMissingMods.add(v);
                    }
                }
            }
            if (!versionMissingMods.isEmpty()) {
                FMLLog.severe("The mod %s (%s) requires mod versions %s to be available", mod.getModId(), mod.getName(), versionMissingMods);
                MissingModsException ret = new MissingModsException(versionMissingMods, mod.getModId(), mod.getName());
                FMLLog.severe(ret.toString());
                missingModsExceptions.add(ret);
            }
        }
        if (wrongMinecraftExceptions.isEmpty() && missingModsExceptions.isEmpty()) {
            FMLLog.finer("All mod requirements are satisfied");
        } else if (missingModsExceptions.size() == 1 && wrongMinecraftExceptions.isEmpty()) {
            throw missingModsExceptions.get(0);
        } else if (wrongMinecraftExceptions.size() == 1 && missingModsExceptions.isEmpty()) {
            throw wrongMinecraftExceptions.get(0);
        } else {
            throw new MultipleModsErrored(wrongMinecraftExceptions, missingModsExceptions);
        }
        reverseDependencies = Multimaps.invertFrom(reqList, ArrayListMultimap.<String, String>create());
        ModSorter sorter = new ModSorter(getActiveModList(), namedMods);
        try {
            FMLLog.finer("Sorting mods into an ordered list");
            List<ModContainer> sortedMods = sorter.sort();
            // Reset active list to the sorted list
            modController.getActiveModList().clear();
            modController.getActiveModList().addAll(sortedMods);
            // And inject the sorted list into the overall list
            mods.removeAll(sortedMods);
            sortedMods.addAll(mods);
            mods = sortedMods;
            FMLLog.finer("Mod sorting completed successfully");
        } catch (ModSortingException sortException) {
            FMLLog.severe("A dependency cycle was detected in the input mod set so an ordering cannot be determined");
            SortingExceptionData<ModContainer> exceptionData = sortException.getExceptionData();
            FMLLog.severe("The first mod in the cycle is %s", exceptionData.getFirstBadNode());
            FMLLog.severe("The mod cycle involves");
            for (ModContainer mc : exceptionData.getVisitedNodes()) {
                FMLLog.severe("%s : before: %s, after: %s", mc.toString(), mc.getDependants(), mc.getDependencies());
            }
            FMLLog.log(Level.ERROR, sortException, "The full error");
            throw sortException;
        }
    } finally {
        FMLLog.fine("Mod sorting data");
        int unprintedMods = mods.size();
        for (ModContainer mod : getActiveModList()) {
            if (!mod.isImmutable()) {
                FMLLog.fine("\t%s(%s:%s): %s (%s)", mod.getModId(), mod.getName(), mod.getVersion(), mod.getSource().getName(), mod.getSortingRules());
                unprintedMods--;
            }
        }
        if (unprintedMods == mods.size()) {
            FMLLog.fine("No user mods found to sort");
        }
    }
}
Also used : ArrayList(java.util.ArrayList) ArtifactVersion(net.minecraftforge.fml.common.versioning.ArtifactVersion) SortingExceptionData(net.minecraftforge.fml.common.toposort.ModSortingException.SortingExceptionData) ModSortingException(net.minecraftforge.fml.common.toposort.ModSortingException) ModSorter(net.minecraftforge.fml.common.toposort.ModSorter) ArtifactVersionNameFunction(net.minecraftforge.fml.common.functions.ArtifactVersionNameFunction)

Example 13 with ArtifactVersion

use of net.minecraftforge.fml.common.versioning.ArtifactVersion in project SpongeForge by SpongePowered.

the class DependencyHandler method findDependency.

private static PluginDependency findDependency(String id, @Nullable PluginDependency current, PluginDependency.LoadOrder loadOrder, Iterable<ArtifactVersion> dependencies, boolean optional) {
    for (ArtifactVersion version : dependencies) {
        String dependencyId = version.getLabel();
        if (dependencyId == null || !dependencyId.equals(id)) {
            continue;
        }
        current = buildDependency(current, loadOrder, version, optional);
    }
    return current;
}
Also used : ArtifactVersion(net.minecraftforge.fml.common.versioning.ArtifactVersion)

Example 14 with ArtifactVersion

use of net.minecraftforge.fml.common.versioning.ArtifactVersion in project LogisticsPipes by RS485.

the class LogisticsClassTransformer method handleLPTransformation.

@SuppressWarnings("unchecked")
private byte[] handleLPTransformation(byte[] bytes) {
    final ClassNode node = new ClassNode();
    ClassReader reader = new ClassReader(bytes);
    reader.accept(node, 0);
    boolean changed = false;
    if (node.visibleAnnotations != null) {
        for (AnnotationNode a : node.visibleAnnotations) {
            if (a.desc.equals("Llogisticspipes/asm/ModDependentInterface;")) {
                if (a.values.size() == 4 && a.values.get(0).equals("modId") && a.values.get(2).equals("interfacePath")) {
                    List<String> modId = (List<String>) a.values.get(1);
                    List<String> interfacePath = (List<String>) a.values.get(3);
                    if (modId.size() != interfacePath.size()) {
                        throw new RuntimeException("The Arrays have to be of the same size.");
                    }
                    for (int i = 0; i < modId.size(); i++) {
                        if (!ModStatusHelper.isModLoaded(modId.get(i))) {
                            interfacesToClearA.add(interfacePath.get(i));
                            interfacesToClearB.add(interfacePath.get(i));
                            for (String inter : node.interfaces) {
                                if (inter.replace("/", ".").equals(interfacePath.get(i))) {
                                    node.interfaces.remove(inter);
                                    changed = true;
                                    break;
                                }
                            }
                        }
                    }
                } else {
                    throw new UnsupportedOperationException("Can't parse the annotations correctly");
                }
            }
        }
    }
    List<MethodNode> methodsToRemove = new ArrayList<>();
    for (MethodNode m : node.methods) {
        if (m.visibleAnnotations != null) {
            for (AnnotationNode a : m.visibleAnnotations) {
                if (a.desc.equals("Llogisticspipes/asm/ModDependentMethod;")) {
                    if (a.values.size() == 2 && a.values.get(0).equals("modId")) {
                        String modId = a.values.get(1).toString();
                        if (!ModStatusHelper.isModLoaded(modId)) {
                            methodsToRemove.add(m);
                            break;
                        }
                    } else {
                        throw new UnsupportedOperationException("Can't parse the annotation correctly");
                    }
                } else if (a.desc.equals("Llogisticspipes/asm/ClientSideOnlyMethodContent;")) {
                    if (FMLCommonHandler.instance().getSide().equals(Side.SERVER)) {
                        m.instructions.clear();
                        m.localVariables.clear();
                        m.tryCatchBlocks.clear();
                        m.visitCode();
                        Label l0 = new Label();
                        m.visitLabel(l0);
                        m.visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/asm/LogisticsASMHookClass", "callingClearedMethod", "()V");
                        Label l1 = new Label();
                        m.visitLabel(l1);
                        m.visitInsn(Opcodes.RETURN);
                        Label l2 = new Label();
                        m.visitLabel(l2);
                        m.visitLocalVariable("this", "Llogisticspipes/network/packets/DummyPacket;", null, l0, l2, 0);
                        m.visitLocalVariable("player", "Lnet/minecraft/entity/player/EntityPlayer;", null, l0, l2, 1);
                        m.visitMaxs(0, 2);
                        m.visitEnd();
                        changed = true;
                        break;
                    }
                } else if (a.desc.equals("Llogisticspipes/asm/ModDependentMethodName;")) {
                    if (a.values.size() == 6 && a.values.get(0).equals("modId") && a.values.get(2).equals("newName") && a.values.get(4).equals("version")) {
                        String modId = a.values.get(1).toString();
                        final String newName = a.values.get(3).toString();
                        final String version = a.values.get(5).toString();
                        boolean loaded = ModStatusHelper.isModLoaded(modId);
                        if (loaded && !version.equals("")) {
                            ModContainer mod = Loader.instance().getIndexedModList().get(modId);
                            if (mod != null) {
                                VersionRange range = VersionParser.parseRange(version);
                                ArtifactVersion artifactVersion = new DefaultArtifactVersion("Version", mod.getVersion());
                                loaded = range.containsVersion(artifactVersion);
                            } else {
                                loaded = false;
                            }
                        }
                        if (loaded) {
                            final String oldName = m.name;
                            m.name = newName;
                            MethodNode newM = new MethodNode(Opcodes.ASM4, m.access, m.name, m.desc, m.signature, m.exceptions.toArray(new String[0])) {

                                @Override
                                public void visitMethodInsn(int opcode, String owner, String name, String desc) {
                                    if (name.equals(oldName) && owner.equals(node.superName)) {
                                        super.visitMethodInsn(opcode, owner, newName, desc);
                                    } else {
                                        super.visitMethodInsn(opcode, owner, name, desc);
                                    }
                                }
                            };
                            m.accept(newM);
                            node.methods.set(node.methods.indexOf(m), newM);
                            changed = true;
                            break;
                        }
                    } else {
                        throw new UnsupportedOperationException("Can't parse the annotation correctly");
                    }
                }
            }
        }
    }
    for (MethodNode m : methodsToRemove) {
        node.methods.remove(m);
    }
    List<FieldNode> fieldsToRemove = new ArrayList<>();
    for (FieldNode f : node.fields) {
        if (f.visibleAnnotations != null) {
            for (AnnotationNode a : f.visibleAnnotations) {
                if (a.desc.equals("Llogisticspipes/asm/ModDependentField;")) {
                    if (a.values.size() == 2 && a.values.get(0).equals("modId")) {
                        String modId = a.values.get(1).toString();
                        if (!ModStatusHelper.isModLoaded(modId)) {
                            fieldsToRemove.add(f);
                            break;
                        }
                    } else {
                        throw new UnsupportedOperationException("Can't parse the annotation correctly");
                    }
                }
            }
        }
    }
    for (FieldNode f : fieldsToRemove) {
        node.fields.remove(f);
    }
    if (!changed && methodsToRemove.isEmpty() && fieldsToRemove.isEmpty()) {
        return bytes;
    }
    ClassWriter writer = new ClassWriter(0);
    node.accept(writer);
    return writer.toByteArray();
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) ModContainer(net.minecraftforge.fml.common.ModContainer) FieldNode(org.objectweb.asm.tree.FieldNode) ArrayList(java.util.ArrayList) Label(org.objectweb.asm.Label) DefaultArtifactVersion(net.minecraftforge.fml.common.versioning.DefaultArtifactVersion) VersionRange(net.minecraftforge.fml.common.versioning.VersionRange) ClassWriter(org.objectweb.asm.ClassWriter) ArtifactVersion(net.minecraftforge.fml.common.versioning.ArtifactVersion) DefaultArtifactVersion(net.minecraftforge.fml.common.versioning.DefaultArtifactVersion) MethodNode(org.objectweb.asm.tree.MethodNode) AnnotationNode(org.objectweb.asm.tree.AnnotationNode) ClassReader(org.objectweb.asm.ClassReader) ArrayList(java.util.ArrayList) List(java.util.List)

Example 15 with ArtifactVersion

use of net.minecraftforge.fml.common.versioning.ArtifactVersion in project AppleCore by squeek502.

the class AppleCoreExample method init.

@EventHandler
public void init(FMLInitializationEvent event) {
    // only add in the test modifications if we are 'alone' in the dev environment
    boolean otherDependantModsExist = false;
    for (ModContainer mod : Loader.instance().getActiveModList()) {
        if (mod.getMod() == this)
            continue;
        for (ArtifactVersion dependency : mod.getRequirements()) {
            if (dependency.getLabel().equals(ModInfo.MODID)) {
                otherDependantModsExist = true;
                break;
            }
        }
        if (otherDependantModsExist)
            break;
    }
    if (!otherDependantModsExist) {
        MinecraftForge.EVENT_BUS.register(new EatingSpeedModifier());
        MinecraftForge.EVENT_BUS.register(new ExhaustionModifier());
        MinecraftForge.EVENT_BUS.register(new FoodEatenResult());
        MinecraftForge.EVENT_BUS.register(new FoodStatsAdditionCanceler());
        MinecraftForge.EVENT_BUS.register(new FoodValuesModifier());
        MinecraftForge.EVENT_BUS.register(new HealthRegenModifier());
        MinecraftForge.EVENT_BUS.register(new HungerRegenModifier());
        MinecraftForge.EVENT_BUS.register(new StarvationModifier());
        MinecraftForge.EVENT_BUS.register(new MaxHungerModifier());
    }
    if (event.getSide() == Side.CLIENT)
        MinecraftForge.EVENT_BUS.register(new FoodValuesTooltipHandler());
}
Also used : ModContainer(net.minecraftforge.fml.common.ModContainer) ArtifactVersion(net.minecraftforge.fml.common.versioning.ArtifactVersion) EventHandler(net.minecraftforge.fml.common.Mod.EventHandler)

Aggregations

ArtifactVersion (net.minecraftforge.fml.common.versioning.ArtifactVersion)15 DefaultArtifactVersion (net.minecraftforge.fml.common.versioning.DefaultArtifactVersion)7 ModContainer (net.minecraftforge.fml.common.ModContainer)4 ArrayList (java.util.ArrayList)2 ArtifactVersionNameFunction (net.minecraftforge.fml.common.functions.ArtifactVersionNameFunction)2 VersionRange (net.minecraftforge.fml.common.versioning.VersionRange)2 EventHandler (com.mcmoddev.basemetals.util.EventHandler)1 FallbackGenerator (com.mcmoddev.lib.oregen.FallbackGenerator)1 MalformedURLException (java.net.MalformedURLException)1 URL (java.net.URL)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Map (java.util.Map)1 Properties (java.util.Properties)1 DummyModContainer (net.minecraftforge.fml.common.DummyModContainer)1 MetadataCollection (net.minecraftforge.fml.common.MetadataCollection)1 MissingModsException (net.minecraftforge.fml.common.MissingModsException)1 EventHandler (net.minecraftforge.fml.common.Mod.EventHandler)1