diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/Main.java b/HMCL/src/main/java/org/jackhuang/hmcl/Main.java index a3b38b8f1..075b10f33 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/Main.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/Main.java @@ -86,6 +86,8 @@ public final class Main extends Application { public static void stopWithoutPlatform() { JFXUtilities.runInFX(() -> { Controllers.getStage().close(); + + Logging.LOG.info("Shutting down executor services."); Schedulers.shutdown(); }); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java index 49fc2d050..c01040128 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -368,6 +368,7 @@ public final class LauncherHelper { logWindow.show(); logWindow.onDone.register(() -> { + logWindow.logLine("Commands: " + StringUtils.makeCommand(process.getCommands()), Log4jLevel.INFO); for (Map.Entry entry : logs) logWindow.logLine(entry.getKey(), entry.getValue()); }); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerController.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerController.java index b6104f2f1..2343e29c1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerController.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerController.java @@ -20,6 +20,7 @@ package org.jackhuang.hmcl.ui; import javafx.fxml.FXML; import javafx.scene.control.ScrollPane; import javafx.scene.layout.VBox; +import org.jackhuang.hmcl.download.MaintainTask; import org.jackhuang.hmcl.download.game.VersionJsonSaveTask; import org.jackhuang.hmcl.game.GameVersion; import org.jackhuang.hmcl.game.Library; @@ -60,7 +61,8 @@ public class InstallerController { Consumer removeAction = x -> { LinkedList newList = new LinkedList<>(version.getLibraries()); newList.remove(library); - new VersionJsonSaveTask(profile.getRepository(), version.setLibraries(newList)) + new MaintainTask(profile.getRepository(), version.setLibraries(newList)) + .then(variables -> new VersionJsonSaveTask(profile.getRepository(), variables.get(MaintainTask.ID))) .with(profile.getRepository().refreshVersionsAsync()) .with(Task.of(Schedulers.javafx(), () -> loadVersion(this.profile, this.versionId))) .start(); diff --git a/HMCL/src/main/resources/assets/log-window-content.html b/HMCL/src/main/resources/assets/log-window-content.html index fdc6d6c0a..2cda7d564 100644 --- a/HMCL/src/main/resources/assets/log-window-content.html +++ b/HMCL/src/main/resources/assets/log-window-content.html @@ -16,6 +16,8 @@ border-style: solid; border-width: 0 0 1px 0; border-color: #dddddd; + white-space: pre-wrap; + word-break: break-all; } .fatal { background-color: #F7A699; } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MaintainTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MaintainTask.java new file mode 100644 index 000000000..1e06aa996 --- /dev/null +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MaintainTask.java @@ -0,0 +1,112 @@ +/* + * Hello Minecraft! Launcher. + * Copyright (C) 2017 huangyuhui + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see {http://www.gnu.org/licenses/}. + */ +package org.jackhuang.hmcl.download; + +import org.jackhuang.hmcl.download.game.VersionJsonSaveTask; +import org.jackhuang.hmcl.game.GameRepository; +import org.jackhuang.hmcl.game.Library; +import org.jackhuang.hmcl.game.Version; +import org.jackhuang.hmcl.task.Schedulers; +import org.jackhuang.hmcl.task.Task; +import org.jackhuang.hmcl.task.TaskResult; +import org.jackhuang.hmcl.util.StringUtils; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +public class MaintainTask extends TaskResult { + + private final GameRepository repository; + private final Version version; + private final String id; + + public MaintainTask(GameRepository repository, Version version) { + this(repository, version, ID); + } + + public MaintainTask(GameRepository repository, Version version, String id) { + this.repository = repository; + this.version = version; + this.id = id; + } + + @Override + public void execute() throws Exception { + Version newVersion = version; + Library forge = null, liteLoader = null, optiFine = null; + List args = new ArrayList<>(StringUtils.tokenize(newVersion.getMinecraftArguments().orElse(""))); + + for (Library library : version.getLibraries()) { + if (library.getGroupId().equalsIgnoreCase("net.minecraftforge") && library.getArtifactId().equalsIgnoreCase("forge")) + forge = library; + + if (library.getGroupId().equalsIgnoreCase("com.mumfrey") && library.getArtifactId().equalsIgnoreCase("liteloader")) + liteLoader = library; + + if (library.getGroupId().equalsIgnoreCase("net.optifine") && library.getArtifactId().equalsIgnoreCase("optifine")) + optiFine = library; + + } + + if (forge == null) { + removeTweakClass(args, "forge"); + } + + if (liteLoader == null) { + removeTweakClass(args, "liteloader"); + } + + if (optiFine == null) { + removeTweakClass(args, "optifine"); + } + + if (liteLoader == null && forge == null && optiFine != null) { + if (!StringUtils.containsOne(args, "optifine.OptiFineTweaker")) { + args.add("--tweakClass"); + args.add("optifine.OptiFineTweaker"); + } + } + + if ((liteLoader != null || forge != null) && optiFine != null) { + // If forge or LiteLoader installed, OptiFine Tweaker will cause crash. + removeTweakClass(args, "optifine"); + } + + setResult(newVersion); + } + + @Override + public String getId() { + return id; + } + + private static void removeTweakClass(List args, String target) { + for (int i = 0; i < args.size(); ++i) { + if (args.get(i).toLowerCase().contains(target)) { + if (i > 0 && args.get(i - 1).equals("--tweakClass")) { + args.remove(i - 1); + args.remove(i - 1); + i -= 2; + } + } + } + } + + public static final String ID = "version"; +} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderInstallTask.java index 92678a0f7..3bcc1bc1f 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderInstallTask.java @@ -96,11 +96,16 @@ public final class LiteLoaderInstallTask extends TaskResult { ); Version tempVersion = version.setLibraries(Lang.merge(remote.getTag().getLibraries(), Collections.singleton(library))); + + String mcArg = version.getMinecraftArguments().orElse(""); + if (mcArg.contains("--tweakClass optifine.OptiFineTweaker")) + mcArg = mcArg.replace("--tweakClass optifine.OptiFineTweaker", ""); + setResult(version .setMainClass("net.minecraft.launchwrapper.Launch") .setLibraries(Lang.merge(tempVersion.getLibraries(), version.getLibraries())) .setLogging(Collections.emptyMap()) - .setMinecraftArguments(version.getMinecraftArguments().orElse("") + " --tweakClass " + remote.getTag().getTweakClass()) + .setMinecraftArguments(mcArg + " --tweakClass " + remote.getTag().getTweakClass()) //.setArguments(Arguments.addGameArguments(Lang.get(version.getArguments()), "--tweakClass", remote.getTag().getTweakClass())) ); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderVersionList.java index 4bd9fa1c7..4e5f16233 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderVersionList.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderVersionList.java @@ -25,7 +25,16 @@ import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.util.Constants; import org.jackhuang.hmcl.util.NetworkUtils; import org.jackhuang.hmcl.util.VersionNumber; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; import java.util.Collection; import java.util.Collections; import java.util.Map; @@ -76,11 +85,18 @@ public final class LiteLoaderVersionList extends VersionList(gameVersion, - v.getVersion().replace("SNAPSHOT", "SNAPSHOT-" + v.getLastSuccessfulBuild()), - snapshot - ? "http://jenkins.liteloader.com/LiteLoader " + gameVersion + "/lastSuccessfulBuild/artifact/build/libs/liteloader-" + v.getVersion() + "-release.jar" - : downloadProvider.injectURL(repository.getUrl() + "com/mumfrey/liteloader/" + gameVersion + "/" + v.getFile()), + version, downloadProvider.injectURL(url), new LiteLoaderRemoteVersionTag(v.getTweakClass(), v.getLibraries()) )); } @@ -89,4 +105,15 @@ public final class LiteLoaderVersionList extends VersionList, ?> closure) { - return of(null, scheduler, closure); + return of(ReflectionHelper.getCaller().toString(), scheduler, closure); } public static Task of(String name, Scheduler scheduler, ExceptionalRunnable closure) { @@ -301,7 +301,7 @@ public abstract class Task { } public static Task of(Scheduler scheduler, ExceptionalRunnable closure) { - return of(null, scheduler, closure); + return of(ReflectionHelper.getCaller().toString(), scheduler, closure); } public static TaskResult ofResult(String id, Callable callable) { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/IOUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/IOUtils.java index ad79ad4b7..7900118e9 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/IOUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/IOUtils.java @@ -36,6 +36,7 @@ public final class IOUtils { if (closeable != null) closeable.close(); } catch (IOException e) { + e.printStackTrace(); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/ReflectionHelper.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/ReflectionHelper.java index 8aac0aecf..f2eb46ffe 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/ReflectionHelper.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/ReflectionHelper.java @@ -146,4 +146,14 @@ public final class ReflectionHelper { .filter(s -> checkParameter(s, args)) .findFirst(); } + + public static StackTraceElement getCaller() { + StackTraceElement[] elements = Thread.currentThread().getStackTrace(); + StackTraceElement caller = elements[2]; + for (int i = 3; i < elements.length; ++i) { + if (!caller.getClassName().equals(elements[i].getClassName())) + return elements[i]; + } + return caller; + } }