Beispiel #1
0
  @Subscribe
  public void buildModList(FMLLoadEvent event) {
    this.modList = loader.getIndexedModList();
    Builder<String, EventBus> eventBus = ImmutableMap.builder();

    for (ModContainer mod : loader.getModList()) {
      EventBus bus = new EventBus(mod.getModId());
      boolean isActive = mod.registerBus(bus, this);
      if (isActive) {
        Level level = Logger.getLogger(mod.getModId()).getLevel();
        FMLLog.log(
            mod.getModId(),
            Level.FINE,
            "Mod Logging channel %s configured at %s level.",
            level == null ? "default" : level);
        FMLLog.log(mod.getModId(), Level.INFO, "Activating mod %s", mod.getModId());
        activeModList.add(mod);
        modStates.put(mod.getModId(), ModState.UNLOADED);
        eventBus.put(mod.getModId(), bus);
      } else {
        FMLLog.log(
            mod.getModId(),
            Level.WARNING,
            "Mod %s has been disabled through configuration",
            mod.getModId());
        modStates.put(mod.getModId(), ModState.UNLOADED);
        modStates.put(mod.getModId(), ModState.DISABLED);
      }
    }

    eventChannels = eventBus.build();
  }
Beispiel #2
0
 private void parseSimpleFieldAnnotation(
     SetMultimap<String, ASMData> annotations,
     String annotationClassName,
     Function<ModContainer, Object> retreiver)
     throws IllegalAccessException {
   String[] annName = annotationClassName.split("\\.");
   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)) {
       if (Loader.isModLoaded(targetMod)) {
         mc = Loader.instance().getIndexedModList().get(targetMod);
       } else {
         mc = null;
       }
     }
     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(
             getModId(),
             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.log(
               getModId(),
               Level.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);
     }
   }
 }
Beispiel #3
0
 public void errorOccurred(ModContainer modContainer, Throwable exception) {
   if (exception instanceof InvocationTargetException) {
     errors.put(modContainer.getModId(), ((InvocationTargetException) exception).getCause());
   } else {
     errors.put(modContainer.getModId(), exception);
   }
 }
  public static void inject(
      ModContainer mod, ASMDataTable data, Side side, ILanguageAdapter languageAdapter) {
    FMLLog.fine("Attempting to inject @SidedProxy classes into %s", mod.getModId());
    Set<ASMData> targets = data.getAnnotationsFor(mod).get(SidedProxy.class.getName());
    ClassLoader mcl = Loader.instance().getModClassLoader();

    for (ASMData targ : targets) {
      try {
        Class<?> proxyTarget = Class.forName(targ.getClassName(), true, mcl);
        Field target = proxyTarget.getDeclaredField(targ.getObjectName());
        if (target == null) {
          // Impossible?
          FMLLog.severe(
              "Attempted to load a proxy type into %s.%s but the field was not found",
              targ.getClassName(), targ.getObjectName());
          throw new LoaderException();
        }

        SidedProxy annotation = target.getAnnotation(SidedProxy.class);
        if (!Strings.isNullOrEmpty(annotation.modId())
            && !annotation.modId().equals(mod.getModId())) {
          FMLLog.fine(
              "Skipping proxy injection for %s.%s since it is not for mod %s",
              targ.getClassName(), targ.getObjectName(), mod.getModId());
          continue;
        }
        String targetType = side.isClient() ? annotation.clientSide() : annotation.serverSide();
        Object proxy = Class.forName(targetType, true, mcl).newInstance();

        if (languageAdapter.supportsStatics() && (target.getModifiers() & Modifier.STATIC) == 0) {
          FMLLog.severe(
              "Attempted to load a proxy type %s into %s.%s, but the field is not static",
              targetType, targ.getClassName(), targ.getObjectName());
          throw new LoaderException();
        }
        if (!target.getType().isAssignableFrom(proxy.getClass())) {
          FMLLog.severe(
              "Attempted to load a proxy type %s into %s.%s, but the types don't match",
              targetType, targ.getClassName(), targ.getObjectName());
          throw new LoaderException();
        }
        languageAdapter.setProxy(target, proxyTarget, proxy);
      } catch (Exception e) {
        FMLLog.log(
            Level.SEVERE,
            e,
            "An error occured trying to load a proxy into %s.%s",
            targ.getAnnotationInfo(),
            targ.getClassName(),
            targ.getObjectName());
        throw new LoaderException(e);
      }
    }

    // Allow language specific proxy injection.
    languageAdapter.setInternalProxies(mod, side, mcl);
  }
Beispiel #5
0
 public void printModStates(StringBuilder ret) {
   for (ModContainer mc : loader.getModList()) {
     ret.append("\n\t")
         .append(mc.getModId())
         .append(" [")
         .append(mc.getName())
         .append("] (")
         .append(mc.getSource().getName())
         .append(") ");
     Joiner.on("->").appendTo(ret, modStates.get(mc.getModId()));
   }
 }
Beispiel #6
0
 public void handleWorldDataSave(
     SaveHandler handler, WorldInfo worldInfo, NBTTagCompound tagCompound) {
   for (ModContainer mc : Loader.instance().getModList()) {
     if (mc instanceof InjectedModContainer) {
       WorldAccessContainer wac = ((InjectedModContainer) mc).getWrappedWorldAccessContainer();
       if (wac != null) {
         NBTTagCompound dataForWriting = wac.getDataForWriting(handler, worldInfo);
         tagCompound.func_74766_a(mc.getModId(), dataForWriting);
       }
     }
   }
 }
 @Override
 public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info) {
   NBTTagCompound fmlData = new NBTTagCompound();
   NBTTagList list = new NBTTagList();
   for (ModContainer mc : Loader.instance().getActiveModList()) {
     NBTTagCompound mod = new NBTTagCompound();
     mod.setString("ModId", mc.getModId());
     mod.setString("ModVersion", mc.getVersion());
     list.appendTag(mod);
   }
   fmlData.setTag("ModList", list);
   NBTTagList itemList = new NBTTagList();
   GameData.writeItemData(itemList);
   fmlData.setTag("ModItemData", itemList);
   return fmlData;
 }
Beispiel #8
0
 public ImmutableBiMap<ModContainer, Object> buildModObjectList() {
   ImmutableBiMap.Builder<ModContainer, Object> builder =
       ImmutableBiMap.<ModContainer, Object>builder();
   for (ModContainer mc : activeModList) {
     if (!mc.isImmutable() && mc.getMod() != null) {
       builder.put(mc, mc.getMod());
     }
     if (mc.getMod() == null && !mc.isImmutable() && state != LoaderState.CONSTRUCTING) {
       FMLLog.severe(
           "There is a severe problem with %s - it appears not to have constructed correctly",
           mc.getModId());
       if (state != LoaderState.CONSTRUCTING) {
         this.errorOccurred(mc, new RuntimeException());
       }
     }
   }
   return builder.build();
 }
Beispiel #9
0
 public void handleWorldDataLoad(
     SaveHandler handler, WorldInfo worldInfo, NBTTagCompound tagCompound) {
   if (getEffectiveSide() != Side.SERVER) {
     return;
   }
   if (handlerSet.contains(handler)) {
     return;
   }
   handlerSet.add(handler);
   Map<String, NBTBase> additionalProperties = Maps.newHashMap();
   worldInfo.setAdditionalProperties(additionalProperties);
   for (ModContainer mc : Loader.instance().getModList()) {
     if (mc instanceof InjectedModContainer) {
       WorldAccessContainer wac = ((InjectedModContainer) mc).getWrappedWorldAccessContainer();
       if (wac != null) {
         wac.readData(
             handler, worldInfo, additionalProperties, tagCompound.func_74775_l(mc.getModId()));
       }
     }
   }
 }
Beispiel #10
0
 @Subscribe
 public void propogateStateMessage(FMLEvent stateEvent) {
   if (stateEvent instanceof FMLPreInitializationEvent) {
     modObjectList = buildModObjectList();
   }
   for (ModContainer mc : activeModList) {
     activeContainer = mc;
     String modId = mc.getModId();
     stateEvent.applyModContainer(activeContainer());
     FMLLog.log(
         modId, Level.FINEST, "Sending event %s to mod %s", stateEvent.getEventType(), modId);
     eventChannels.get(modId).post(stateEvent);
     FMLLog.log(modId, Level.FINEST, "Sent event %s to mod %s", stateEvent.getEventType(), modId);
     activeContainer = null;
     if (stateEvent instanceof FMLStateEvent) {
       if (!errors.containsKey(modId)) {
         modStates.put(modId, ((FMLStateEvent) stateEvent).getModState());
       } else {
         modStates.put(modId, ModState.ERRORED);
       }
     }
   }
 }
Beispiel #11
0
  /**
   * Called from the hook to start mod loading. We trigger the {@link #identifyMods()} and
   * Constructing, Preinitalization, and Initalization phases here. Finally, the mod list is frozen
   * completely and is consider immutable from then on.
   */
  public void loadMods() {
    progressBar = ProgressManager.push("Loading", 7);
    progressBar.step("Constructing Mods");
    initializeLoader();
    mods = Lists.newArrayList();
    namedMods = Maps.newHashMap();
    modController = new LoadController(this);
    modController.transition(LoaderState.LOADING, false);
    discoverer = identifyMods();
    ModAPIManager.INSTANCE.manageAPI(modClassLoader, discoverer);
    disableRequestedMods();
    modController.distributeStateMessage(FMLLoadEvent.class);
    sortModList();
    ModAPIManager.INSTANCE.cleanupAPIContainers(modController.getActiveModList());
    ModAPIManager.INSTANCE.cleanupAPIContainers(mods);
    mods = ImmutableList.copyOf(mods);
    for (File nonMod : discoverer.getNonModLibs()) {
      if (nonMod.isFile()) {
        FMLLog.info(
            "FML has found a non-mod file %s in your mods directory. It will now be injected into your classpath. This could severe stability issues, it should be removed if possible.",
            nonMod.getName());
        try {
          modClassLoader.addFile(nonMod);
        } catch (MalformedURLException e) {
          FMLLog.log(
              Level.ERROR,
              e,
              "Encountered a weird problem with non-mod file injection : %s",
              nonMod.getName());
        }
      }
    }
    modController.transition(LoaderState.CONSTRUCTING, false);
    modController.distributeStateMessage(
        LoaderState.CONSTRUCTING, modClassLoader, discoverer.getASMTable(), reverseDependencies);

    List<ModContainer> mods = Lists.newArrayList();
    mods.addAll(getActiveModList());
    Collections.sort(
        mods,
        new Comparator<ModContainer>() {
          @Override
          public int compare(ModContainer o1, ModContainer o2) {
            return o1.getModId().compareTo(o2.getModId());
          }
        });

    FMLLog.fine("Mod signature data");
    FMLLog.fine(" \tValid Signatures:");
    for (ModContainer mod : getActiveModList()) {
      if (mod.getSigningCertificate() != null)
        FMLLog.fine(
            "\t\t(%s) %s\t(%s\t%s)\t%s",
            CertificateHelper.getFingerprint(mod.getSigningCertificate()),
            mod.getModId(),
            mod.getName(),
            mod.getVersion(),
            mod.getSource().getName());
    }
    FMLLog.fine(" \tMissing Signatures:");
    for (ModContainer mod : getActiveModList()) {
      if (mod.getSigningCertificate() == null)
        FMLLog.fine(
            "\t\t%s\t(%s\t%s)\t%s",
            mod.getModId(), mod.getName(), mod.getVersion(), mod.getSource().getName());
    }
    if (getActiveModList().isEmpty()) {
      FMLLog.fine("No user mod signature data found");
    }
    progressBar.step("Initializing mods Phase 1");
    modController.transition(LoaderState.PREINITIALIZATION, false);
  }
Beispiel #12
0
 @Override
 public int compare(ModContainer o1, ModContainer o2) {
   return o1.getModId().compareTo(o2.getModId());
 }
Beispiel #13
0
  /**
   * 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");
    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());
          throw new WrongMinecraftVersionException(mod);
        }
        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));
          }
          throw new MissingModsException(versionMissingMods, mod.getModId(), mod.getName());
        }
        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);
          throw new MissingModsException(versionMissingMods, mod.getModId(), mod.getName());
        }
      }

      FMLLog.finer("All mod requirements are satisfied");

      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");
      }
    }
  }
Beispiel #14
0
 public ModState getModState(ModContainer selectedMod) {
   return Iterables.getLast(modStates.get(selectedMod.getModId()), ModState.AVAILABLE);
 }