void updateProperties() { Config config = MCPatcherUtils.config; Element mods = config.getMods(); if (mods == null) { return; } HashMap<String, Element> oldElements = new HashMap<String, Element>(); while (mods.hasChildNodes()) { Node node = mods.getFirstChild(); if (node instanceof Element) { Element element = (Element) node; String name = config.getText(element, Config.TAG_NAME); if (name != null) { oldElements.put(name, element); } } mods.removeChild(node); } for (Mod mod : modsByIndex) { if (mod.internal) { continue; } Element element = oldElements.get(mod.getName()); if (element == null) { defaultModElement(mod); } else { config.setText( element, Config.TAG_ENABLED, Boolean.toString(mod.isEnabled() && mod.okToApply())); updateModElement(mod, element); mods.appendChild(element); oldElements.remove(mod.getName()); } } }
ModList() { MinecraftVersion version = MCPatcher.minecraft.getVersion(); baseMod = new BaseMod(version); baseMod.internal = true; texturePackMod = new BaseTexturePackMod(version); texturePackMod.internal = true; addNoReplace(baseMod); addNoReplace(texturePackMod); }
HashMap<String, String> getReverseMap() { HashMap<String, String> map = new HashMap<String, String>(); for (Mod mod : modsByIndex) { for (Map.Entry<String, String> entry : mod.getClassMap().getReverseClassMap().entrySet()) { map.put(entry.getKey(), entry.getValue()); } } return map; }
ArrayList<Mod> getSelected() { ArrayList<Mod> list = new ArrayList<Mod>(); for (Mod mod : modsByIndex) { if (mod.okToApply() && mod.isEnabled()) { list.add(mod); } } return list; }
void remove(Mod mod) { String name = mod.getName(); for (int i = 0; i < modsByIndex.size(); i++) { if (modsByIndex.get(i) == mod) { modsByIndex.remove(i); modsByName.remove(name); } } mod.close(); }
int addLast(Mod mod) { String name = mod.getName(); Mod oldMod = modsByName.get(name); if (oldMod != null) { remove(oldMod); } modsByIndex.add(mod); modsByName.put(name, mod); mod.setRefs(); return indexOfVisible(mod); }
int replace(Mod oldMod, Mod newMod) { int index = indexOf(oldMod); if (index >= 0 && oldMod.getName().equals(newMod.getName())) { modsByIndex.set(index, newMod); modsByName.put(newMod.getName(), newMod); oldMod.close(); return indexOfVisible(newMod); } else { remove(oldMod); return addFirst(newMod); } }
void enableValidMods(boolean enableAll) { for (int i = modsByIndex.size() - 1; i >= 0; i--) { Mod mod = modsByIndex.get(i); boolean enabled = mod.okToApply(); if (enabled) { if (enableAll) { selectMod(mod, true); } } else { selectMod(mod, false); } } }
private boolean addNoReplace(Mod mod) { if (mod == null) { return false; } String name = mod.getName(); if (modsByName.containsKey(name)) { Logger.log(Logger.LOG_MOD, "WARNING: duplicate mod %s ignored", name); return false; } mod.setRefs(); modsByName.put(name, mod); modsByIndex.add(mod); mod.setEnabled(mod.defaultEnabled); mod.loadOptions(); return true; }
private void updateModElement(Mod mod, Element element) { Config config = MCPatcherUtils.config; if (mod instanceof ExternalMod) { ExternalMod extmod = (ExternalMod) mod; config.setText(element, Config.TAG_TYPE, Config.VAL_EXTERNAL_ZIP); config.setText(element, Config.TAG_PATH, extmod.zipFile.getName()); Element files = config.getElement(element, Config.TAG_FILES); while (files.hasChildNodes()) { files.removeChild(files.getFirstChild()); } for (Map.Entry<String, String> entry : extmod.fileMap.entrySet()) { Element fileElem = config.xml.createElement(Config.TAG_FILE); Element pathElem = config.xml.createElement(Config.TAG_FROM); pathElem.appendChild(config.xml.createTextNode(entry.getValue())); fileElem.appendChild(pathElem); pathElem = config.xml.createElement(Config.TAG_TO); pathElem.appendChild(config.xml.createTextNode(entry.getKey())); fileElem.appendChild(pathElem); files.appendChild(fileElem); } } else if (mod.customJar == null) { config.setText(element, Config.TAG_TYPE, Config.VAL_BUILTIN); } else { config.setText(element, Config.TAG_TYPE, Config.VAL_EXTERNAL_JAR); config.setText(element, Config.TAG_PATH, mod.customJar.getPath()); config.setText(element, Config.TAG_CLASS, mod.getClass().getCanonicalName()); } }
private void loadCustomModsFromJar(File file) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException { Logger.log(Logger.LOG_JAR, "Opening %s", file.getPath()); final JarFile jar = new JarFile(file); URLClassLoader loader = new URLClassLoader(new URL[] {file.toURI().toURL()}, getClass().getClassLoader()); for (JarEntry entry : Collections.list(jar.entries())) { if (!entry.isDirectory() && MinecraftJar.isClassFile(entry.getName())) { Mod mod = loadCustomMod(loader, ClassMap.filenameToClassName(entry.getName())); if (addNoReplace(mod)) { Logger.log(Logger.LOG_MOD, "new %s()", mod.getClass().getName()); mod.customJar = file; } } } }
private Element defaultModElement(Mod mod) { Config config = MCPatcherUtils.config; Element mods = config.getMods(); if (mods == null) { return null; } Element element = config.getMod(mod.getName()); config.setText(element, Config.TAG_ENABLED, Boolean.toString(mod.defaultEnabled)); updateModElement(mod, element); return element; }
private void enableMod(HashMap<Mod, Boolean> inst, Mod mod, boolean recursive) throws ModDependencyException { if (mod == null) { return; } // Logger.log(Logger.LOG_MOD, "%senabling %s", (recursive ? " " : ""), mod.getName()); if (!mod.okToApply()) { throw new ModDependencyException(mod.getName() + " cannot be applied"); } if (inst.containsKey(mod)) { if (!inst.get(mod)) { throw new ModDependencyException(mod.getName() + " is both conflicting and required"); } return; } else { inst.put(mod, true); } for (Mod.Dependency dep : mod.dependencies) { Mod dmod = modsByName.get(dep.name); if (dep.required) { if (dmod == null) { throw new ModDependencyException("dependent mod " + dep.name + " not available"); } else { enableMod(inst, dmod, true); } } else { disableMod(inst, dmod, true); } } for (Mod dmod : modsByIndex) { if (dmod != mod) { for (Mod.Dependency dep : dmod.dependencies) { if (dep.name.equals(mod.getName()) && !dep.required) { disableMod(inst, dmod, true); } } } } }
private void disableMod(HashMap<Mod, Boolean> inst, Mod mod, boolean recursive) throws ModDependencyException { if (mod == null) { return; } // Logger.log(Logger.LOG_MOD, "%sdisabling %s", (recursive ? " " : ""), mod.getName()); if (inst.containsKey(mod)) { if (inst.get(mod)) { throw new ModDependencyException(mod.getName() + " is both conflicting and required"); } return; } else { inst.put(mod, false); } for (Mod dmod : modsByIndex) { if (dmod != mod) { for (Mod.Dependency dep : dmod.dependencies) { if (dep.name.equals(mod.getName()) && dep.required) { disableMod(inst, dmod, true); } } } } }
private boolean dependsOn(Mod mod1, Mod mod2) { if (mod1 == null || mod2 == null) { return false; } if (mod1 == mod2) { return true; } for (Mod.Dependency dep : mod1.dependencies) { if (dep.required && !dep.name.equals(mod1.getName()) && dependsOn(modsByName.get(dep.name), mod2)) { return true; } } return false; }
void selectMod(Mod mod, boolean enable) { HashMap<Mod, Boolean> changes = new HashMap<Mod, Boolean>(); try { if (enable) { enableMod(changes, mod, false); } else { disableMod(changes, mod, false); } } catch (ModDependencyException e) { Logger.log(e); } for (Map.Entry<Mod, Boolean> entry : changes.entrySet()) { mod = entry.getKey(); mod.setEnabled(entry.getValue()); } refreshInternalMods(); }
private void refreshInternalMods() { modsByIndex.remove(baseMod); modsByIndex.remove(texturePackMod); modsByIndex.add(0, baseMod); modsByIndex.add(1, texturePackMod); outer: while (true) { for (int i = 0; i < modsByIndex.size() - 1; i++) { Mod mod1 = modsByIndex.get(i); Mod mod2 = modsByIndex.get(i + 1); if (mod1.internal && !dependsOn(mod2, mod1)) { modsByIndex.set(i, mod2); modsByIndex.set(i + 1, mod1); continue outer; } } break; } for (Mod mod : modsByIndex) { if (mod.internal) { mod.setEnabled(false); } } HashMap<Mod, Boolean> changes = new HashMap<Mod, Boolean>(); for (Mod mod : modsByIndex) { try { if (mod.internal) { // nothing } else if (mod.isEnabled()) { enableMod(changes, mod, false); } else { disableMod(changes, mod, false); } } catch (ModDependencyException e) { Logger.log(e); } } for (Map.Entry<Mod, Boolean> entry : changes.entrySet()) { Mod mod = entry.getKey(); mod.setEnabled(entry.getValue()); } }
/** * Returns BSA object associated with mod, or null if there is none. * * @param m * @return */ public static BSA getBSA(Mod m) { return getBSA(m.getInfo()); }
void loadSavedMods() { Config config = MCPatcherUtils.config; Element mods = config.getMods(); if (mods == null) { return; } NodeList list = mods.getElementsByTagName(Config.TAG_MOD); ArrayList<Element> invalidEntries = new ArrayList<Element>(); for (int i = 0; i < list.getLength(); i++) { Element element = (Element) list.item(i); String name = config.getText(element, Config.TAG_NAME); String type = config.getText(element, Config.TAG_TYPE); String enabled = config.getText(element, Config.TAG_ENABLED); Mod mod = null; if (name == null || type == null) { invalidEntries.add(element); } else if (type.equals(Config.VAL_BUILTIN)) { for (BuiltInMod builtInMod : builtInMods) { if (name.equals(builtInMod.name) && (MCPatcher.experimentalMods || !builtInMod.experimental)) { mod = newModInstance(builtInMod.modClass); } } if (mod == null) { invalidEntries.add(element); } } else if (type.equals(Config.VAL_EXTERNAL_ZIP)) { String path = config.getText(element, Config.TAG_PATH); Element files = config.getElement(element, Config.TAG_FILES); if (path != null && files != null) { File file = new File(path); if (file.exists()) { HashMap<String, String> fileMap = new HashMap<String, String>(); NodeList fileNodes = files.getElementsByTagName(Config.TAG_FILE); for (int j = 0; j < fileNodes.getLength(); j++) { Element fileElem = (Element) fileNodes.item(j); String from = config.getText(fileElem, Config.TAG_FROM); String to = config.getText(fileElem, Config.TAG_TO); if (from != null && to != null) { fileMap.put(to, from); } } try { mod = new ExternalMod(new ZipFile(file), fileMap); } catch (IOException e) { Logger.log(e); } } } else { invalidEntries.add(element); } } else if (type.equals(Config.VAL_EXTERNAL_JAR)) { String path = config.getText(element, Config.TAG_PATH); String className = config.getText(element, Config.TAG_CLASS); if (path != null && className != null) { File file = new File(path); if (file.exists()) { mod = loadCustomMod(file, className); if (mod != null) { mod.customJar = file; } } } else { invalidEntries.add(element); } } else { invalidEntries.add(element); } if (mod != null) { if (addNoReplace(mod)) { if (enabled != null) { mod.setEnabled(Boolean.parseBoolean(enabled)); } } } } for (Element element : invalidEntries) { mods.removeChild(element); } refreshInternalMods(); }
/** * @param m * @return */ public static boolean hasBSA(Mod m) { return hasBSA(m.getInfo()); }
void close() { for (Mod mod : modsByIndex) { mod.close(); } }