mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-11 12:56:53 -04:00
Modpack updates UI
This commit is contained in:
parent
e8316de160
commit
1a572be52e
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
|
||||||
|
*
|
||||||
|
* 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.game;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||||
|
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||||
|
import org.jackhuang.hmcl.download.GameBuilder;
|
||||||
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
|
|
||||||
|
import java.net.Proxy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author huangyuhui
|
||||||
|
*/
|
||||||
|
public class HMCLDependencyManager extends DefaultDependencyManager {
|
||||||
|
private final Profile profile;
|
||||||
|
|
||||||
|
public HMCLDependencyManager(Profile profile, DownloadProvider downloadProvider) {
|
||||||
|
this(profile, downloadProvider, Proxy.NO_PROXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HMCLDependencyManager(Profile profile, DownloadProvider downloadProvider, Proxy proxy) {
|
||||||
|
super(profile.getRepository(), downloadProvider, proxy);
|
||||||
|
|
||||||
|
this.profile = profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GameBuilder gameBuilder() {
|
||||||
|
return new HMCLGameBuilder(profile);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
|
||||||
|
*
|
||||||
|
* 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.game;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||||
|
import org.jackhuang.hmcl.download.DefaultGameBuilder;
|
||||||
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
|
import org.jackhuang.hmcl.task.Task;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author huangyuhui
|
||||||
|
*/
|
||||||
|
public class HMCLGameBuilder extends DefaultGameBuilder {
|
||||||
|
private final Profile profile;
|
||||||
|
|
||||||
|
public HMCLGameBuilder(Profile profile) {
|
||||||
|
super(profile.getDependency());
|
||||||
|
|
||||||
|
this.profile = profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Task downloadGameAsync(String gameVersion, Version version) {
|
||||||
|
return new HMCLGameDownloadTask(profile, gameVersion, version);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
|
||||||
|
*
|
||||||
|
* 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.game;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||||
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
|
import org.jackhuang.hmcl.setting.Settings;
|
||||||
|
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||||
|
import org.jackhuang.hmcl.task.Task;
|
||||||
|
import org.jackhuang.hmcl.util.FileUtils;
|
||||||
|
import org.jackhuang.hmcl.util.Logging;
|
||||||
|
import org.jackhuang.hmcl.util.NetworkUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author huangyuhui
|
||||||
|
*/
|
||||||
|
public class HMCLGameDownloadTask extends Task {
|
||||||
|
private final Profile profile;
|
||||||
|
private final String gameVersion;
|
||||||
|
private final Version version;
|
||||||
|
private final List<Task> dependencies = new LinkedList<>();
|
||||||
|
|
||||||
|
public HMCLGameDownloadTask(Profile profile, String gameVersion, Version version) {
|
||||||
|
this.profile = profile;
|
||||||
|
this.gameVersion = gameVersion;
|
||||||
|
this.version = version;
|
||||||
|
|
||||||
|
setSignificance(TaskSignificance.MINOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Task> getDependencies() {
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws IOException {
|
||||||
|
File jar = profile.getRepository().getVersionJar(version);
|
||||||
|
|
||||||
|
File cache = new File(Settings.INSTANCE.getCommonPath(), "jars/" + gameVersion + ".jar");
|
||||||
|
if (cache.exists())
|
||||||
|
try {
|
||||||
|
FileUtils.copyFile(cache, jar);
|
||||||
|
return;
|
||||||
|
} catch (IOException e) {
|
||||||
|
Logging.LOG.log(Level.SEVERE, "Unable to copy cached Minecraft jar from " + cache + " to " + jar, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies.add(new FileDownloadTask(
|
||||||
|
NetworkUtils.toURL(profile.getDependency().getDownloadProvider().injectURL(version.getDownloadInfo().getUrl())),
|
||||||
|
jar,
|
||||||
|
profile.getDependency().getProxy(),
|
||||||
|
version.getDownloadInfo().getSha1()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -33,10 +33,7 @@ import org.jackhuang.hmcl.util.Logging;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class HMCLGameRepository extends DefaultGameRepository {
|
public class HMCLGameRepository extends DefaultGameRepository {
|
||||||
@ -192,6 +189,15 @@ public class HMCLGameRepository extends DefaultGameRepository {
|
|||||||
Lang.invoke(() -> FileUtils.writeText(getVersionSettingFile(id), GSON.toJson(versionSettings.get(id))));
|
Lang.invoke(() -> FileUtils.writeText(getVersionSettingFile(id), GSON.toJson(versionSettings.get(id))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean forbidsVersion(String id) {
|
||||||
|
return FORBIDDEN.contains(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getModpackConfiguration(String version) {
|
||||||
|
return new File(getRunDirectory(version), "modpack.cfg");
|
||||||
|
}
|
||||||
|
|
||||||
public void markVersionAsModpack(String id) {
|
public void markVersionAsModpack(String id) {
|
||||||
beingModpackVersions.add(id);
|
beingModpackVersions.add(id);
|
||||||
}
|
}
|
||||||
@ -204,5 +210,7 @@ public class HMCLGameRepository extends DefaultGameRepository {
|
|||||||
.registerTypeAdapter(VersionSetting.class, VersionSetting.Serializer.INSTANCE)
|
.registerTypeAdapter(VersionSetting.class, VersionSetting.Serializer.INSTANCE)
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
|
private static final HashSet<String> FORBIDDEN = new HashSet<>(Arrays.asList("modpack", "minecraftinstance", "manifest"));
|
||||||
|
|
||||||
private static final String PROFILE = "{\"selectedProfile\": \"(Default)\",\"profiles\": {\"(Default)\": {\"name\": \"(Default)\"}},\"clientToken\": \"88888888-8888-8888-8888-888888888888\"}";
|
private static final String PROFILE = "{\"selectedProfile\": \"(Default)\",\"profiles\": {\"(Default)\": {\"name\": \"(Default)\"}},\"clientToken\": \"88888888-8888-8888-8888-888888888888\"}";
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ public final class HMCLModpackInstallTask extends Task {
|
|||||||
this.modpack = modpack;
|
this.modpack = modpack;
|
||||||
this.run = repository.getRunDirectory(name);
|
this.run = repository.getRunDirectory(name);
|
||||||
|
|
||||||
File json = new File(run, "modpack.json");
|
File json = repository.getModpackConfiguration(name);
|
||||||
if (repository.hasVersion(name) && !json.exists())
|
if (repository.hasVersion(name) && !json.exists())
|
||||||
throw new IllegalArgumentException("Version " + name + " already exists");
|
throw new IllegalArgumentException("Version " + name + " already exists");
|
||||||
|
|
||||||
@ -64,8 +64,13 @@ public final class HMCLModpackInstallTask extends Task {
|
|||||||
|
|
||||||
ModpackConfiguration<Modpack> config = null;
|
ModpackConfiguration<Modpack> config = null;
|
||||||
try {
|
try {
|
||||||
if (json.exists())
|
if (json.exists()) {
|
||||||
config = Constants.GSON.fromJson(FileUtils.readText(json), new TypeToken<ModpackConfiguration<Modpack>>(){}.getType());
|
config = Constants.GSON.fromJson(FileUtils.readText(json), new TypeToken<ModpackConfiguration<Modpack>>() {
|
||||||
|
}.getType());
|
||||||
|
|
||||||
|
if (!MODPACK_TYPE.equals(config.getType()))
|
||||||
|
throw new IllegalArgumentException("Version " + name + " is not a HMCL modpack. Cannot update this version.");
|
||||||
|
}
|
||||||
} catch (JsonParseException | IOException ignore) {
|
} catch (JsonParseException | IOException ignore) {
|
||||||
}
|
}
|
||||||
dependents.add(new ModpackInstallTask<>(zipFile, run, "minecraft/", it -> !Objects.equals(it, "minecraft/pack.json"), config));
|
dependents.add(new ModpackInstallTask<>(zipFile, run, "minecraft/", it -> !Objects.equals(it, "minecraft/pack.json"), config));
|
||||||
@ -86,6 +91,8 @@ public final class HMCLModpackInstallTask extends Task {
|
|||||||
String json = CompressingUtils.readTextZipEntry(zipFile, "minecraft/pack.json");
|
String json = CompressingUtils.readTextZipEntry(zipFile, "minecraft/pack.json");
|
||||||
Version version = Constants.GSON.fromJson(json, Version.class).setJar(null);
|
Version version = Constants.GSON.fromJson(json, Version.class).setJar(null);
|
||||||
dependencies.add(new VersionJsonSaveTask(repository, version));
|
dependencies.add(new VersionJsonSaveTask(repository, version));
|
||||||
dependencies.add(new MinecraftInstanceTask<>(zipFile, "minecraft/", modpack, new File(run, "modpack.json")));
|
dependencies.add(new MinecraftInstanceTask<>(zipFile, "minecraft/", modpack, MODPACK_TYPE, repository.getModpackConfiguration(name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final String MODPACK_TYPE = "HMCL";
|
||||||
}
|
}
|
||||||
|
@ -17,20 +17,26 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.game;
|
package org.jackhuang.hmcl.game;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.mod.CurseManifest;
|
import com.google.gson.JsonParseException;
|
||||||
import org.jackhuang.hmcl.mod.Modpack;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import org.jackhuang.hmcl.mod.MultiMCInstanceConfiguration;
|
import org.jackhuang.hmcl.mod.*;
|
||||||
import org.jackhuang.hmcl.setting.EnumGameDirectory;
|
import org.jackhuang.hmcl.setting.EnumGameDirectory;
|
||||||
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.setting.VersionSetting;
|
import org.jackhuang.hmcl.setting.VersionSetting;
|
||||||
|
import org.jackhuang.hmcl.task.Task;
|
||||||
|
import org.jackhuang.hmcl.util.Constants;
|
||||||
|
import org.jackhuang.hmcl.util.FileUtils;
|
||||||
import org.jackhuang.hmcl.util.Lang;
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public final class ModpackHelper {
|
public final class ModpackHelper {
|
||||||
private ModpackHelper() {}
|
private ModpackHelper() {}
|
||||||
|
|
||||||
public static Modpack readModpackManifest(File file) {
|
public static Modpack readModpackManifest(File file) throws UnsupportedModpackException {
|
||||||
try {
|
try {
|
||||||
return CurseManifest.readCurseForgeModpackManifest(file);
|
return CurseManifest.readCurseForgeModpackManifest(file);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -49,7 +55,54 @@ public final class ModpackHelper {
|
|||||||
// ignore it, not a valid MultiMC modpack.
|
// ignore it, not a valid MultiMC modpack.
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException("Modpack file " + file + " is not supported.");
|
throw new UnsupportedModpackException(file.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ModpackConfiguration<T> readModpackConfiguration(File file) throws IOException {
|
||||||
|
if (!file.exists())
|
||||||
|
throw new FileNotFoundException(file.getPath());
|
||||||
|
else
|
||||||
|
try {
|
||||||
|
return Constants.GSON.fromJson(FileUtils.readText(file), new TypeToken<ModpackConfiguration<T>>() {
|
||||||
|
}.getType());
|
||||||
|
} catch (JsonParseException e) {
|
||||||
|
throw new IOException("Malformed modpack configuration");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getManifestType(Object manifest) throws UnsupportedModpackException {
|
||||||
|
if (manifest instanceof HMCLModpackManifest)
|
||||||
|
return HMCLModpackInstallTask.MODPACK_TYPE;
|
||||||
|
else if (manifest instanceof MultiMCInstanceConfiguration)
|
||||||
|
return MultiMCModpackInstallTask.MODPACK_TYPE;
|
||||||
|
else if (manifest instanceof CurseManifest)
|
||||||
|
return CurseInstallTask.MODPACK_TYPE;
|
||||||
|
else
|
||||||
|
throw new UnsupportedModpackException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Task getUpdateTask(Profile profile, File zipFile, String name, ModpackConfiguration configuration) throws UnsupportedModpackException, MismatchedModpackTypeException, IOException {
|
||||||
|
Modpack modpack = ModpackHelper.readModpackManifest(zipFile);
|
||||||
|
|
||||||
|
switch (configuration.getType()) {
|
||||||
|
case CurseInstallTask.MODPACK_TYPE:
|
||||||
|
if (!(modpack.getManifest() instanceof CurseManifest))
|
||||||
|
throw new MismatchedModpackTypeException(CurseInstallTask.MODPACK_TYPE, getManifestType(modpack.getManifest()));
|
||||||
|
|
||||||
|
return new CurseInstallTask(profile.getDependency(), zipFile, (CurseManifest) modpack.getManifest(), name);
|
||||||
|
case MultiMCModpackInstallTask.MODPACK_TYPE:
|
||||||
|
if (!(modpack.getManifest() instanceof MultiMCInstanceConfiguration))
|
||||||
|
throw new MismatchedModpackTypeException(MultiMCModpackInstallTask.MODPACK_TYPE, getManifestType(modpack.getManifest()));
|
||||||
|
|
||||||
|
return new MultiMCModpackInstallTask(profile.getDependency(), zipFile, (MultiMCInstanceConfiguration) modpack.getManifest(), name);
|
||||||
|
case HMCLModpackInstallTask.MODPACK_TYPE:
|
||||||
|
if (!(modpack.getManifest() instanceof HMCLModpackManifest))
|
||||||
|
throw new MismatchedModpackTypeException(HMCLModpackInstallTask.MODPACK_TYPE, getManifestType(modpack.getManifest()));
|
||||||
|
|
||||||
|
return new HMCLModpackInstallTask(profile, zipFile, modpack, name);
|
||||||
|
default:
|
||||||
|
throw new UnsupportedModpackException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void toVersionSetting(MultiMCInstanceConfiguration c, VersionSetting vs) {
|
public static void toVersionSetting(MultiMCInstanceConfiguration c, VersionSetting vs) {
|
||||||
@ -88,4 +141,6 @@ public final class ModpackHelper {
|
|||||||
vs.setHeight(c.getHeight());
|
vs.setHeight(c.getHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ import org.jackhuang.hmcl.task.Scheduler;
|
|||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public final class MultiMCInstallVersionSettingTask extends Task {
|
public final class MultiMCInstallVersionSettingTask extends Task {
|
||||||
private final Profile profile;
|
private final Profile profile;
|
||||||
private final MultiMCInstanceConfiguration manifest;
|
private final MultiMCInstanceConfiguration manifest;
|
||||||
@ -42,7 +44,8 @@ public final class MultiMCInstallVersionSettingTask extends Task {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
VersionSetting vs = profile.specializeVersionSetting(version);
|
profile.getRepository().refreshVersions();
|
||||||
|
VersionSetting vs = Objects.requireNonNull(profile.specializeVersionSetting(version));
|
||||||
ModpackHelper.toVersionSetting(manifest, vs);
|
ModpackHelper.toVersionSetting(manifest, vs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ package org.jackhuang.hmcl.setting;
|
|||||||
import com.google.gson.*;
|
import com.google.gson.*;
|
||||||
import javafx.beans.InvalidationListener;
|
import javafx.beans.InvalidationListener;
|
||||||
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||||
|
import org.jackhuang.hmcl.game.HMCLDependencyManager;
|
||||||
import org.jackhuang.hmcl.game.HMCLGameRepository;
|
import org.jackhuang.hmcl.game.HMCLGameRepository;
|
||||||
import org.jackhuang.hmcl.mod.ModManager;
|
import org.jackhuang.hmcl.mod.ModManager;
|
||||||
import org.jackhuang.hmcl.util.ImmediateObjectProperty;
|
import org.jackhuang.hmcl.util.ImmediateObjectProperty;
|
||||||
@ -105,8 +106,8 @@ public final class Profile {
|
|||||||
return modManager;
|
return modManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DefaultDependencyManager getDependency() {
|
public HMCLDependencyManager getDependency() {
|
||||||
return new DefaultDependencyManager(repository, Settings.INSTANCE.getDownloadProvider(), Settings.INSTANCE.getProxy());
|
return new HMCLDependencyManager(this, Settings.INSTANCE.getDownloadProvider(), Settings.INSTANCE.getProxy());
|
||||||
}
|
}
|
||||||
|
|
||||||
public VersionSetting getVersionSetting(String id) {
|
public VersionSetting getVersionSetting(String id) {
|
||||||
|
@ -27,6 +27,7 @@ import org.jackhuang.hmcl.Main;
|
|||||||
import org.jackhuang.hmcl.setting.Settings;
|
import org.jackhuang.hmcl.setting.Settings;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.ui.construct.InputDialogPane;
|
import org.jackhuang.hmcl.ui.construct.InputDialogPane;
|
||||||
|
import org.jackhuang.hmcl.ui.construct.MessageBox;
|
||||||
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
||||||
import org.jackhuang.hmcl.util.JavaVersion;
|
import org.jackhuang.hmcl.util.JavaVersion;
|
||||||
|
|
||||||
@ -112,11 +113,19 @@ public final class Controllers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void dialog(String text, String title) {
|
public static void dialog(String text, String title) {
|
||||||
dialog(text, title, null);
|
dialog(text, title, MessageBox.INFORMATION_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void dialog(String text, String title, Runnable onAccept) {
|
public static void dialog(String text, String title, int type) {
|
||||||
dialog(new MessageDialogPane(text, title, decorator.getDialog(), onAccept));
|
dialog(text, title, type, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void dialog(String text, String title, int type, Runnable onAccept) {
|
||||||
|
dialog(new MessageDialogPane(text, title, decorator.getDialog(), MessageBox.INFORMATION_MESSAGE, onAccept));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void confirmDialog(String text, String title, Runnable onAccept, Runnable onCacnel) {
|
||||||
|
dialog(new MessageDialogPane(text, title, decorator.getDialog(), onAccept, onCacnel));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void inputDialog(String text, Consumer<String> onResult) {
|
public static void inputDialog(String text, Consumer<String> onResult) {
|
||||||
|
@ -35,15 +35,25 @@ import org.jackhuang.hmcl.event.ProfileLoadingEvent;
|
|||||||
import org.jackhuang.hmcl.event.RefreshedVersionsEvent;
|
import org.jackhuang.hmcl.event.RefreshedVersionsEvent;
|
||||||
import org.jackhuang.hmcl.game.GameVersion;
|
import org.jackhuang.hmcl.game.GameVersion;
|
||||||
import org.jackhuang.hmcl.game.LauncherHelper;
|
import org.jackhuang.hmcl.game.LauncherHelper;
|
||||||
|
import org.jackhuang.hmcl.game.ModpackHelper;
|
||||||
import org.jackhuang.hmcl.game.Version;
|
import org.jackhuang.hmcl.game.Version;
|
||||||
|
import org.jackhuang.hmcl.mod.MismatchedModpackTypeException;
|
||||||
|
import org.jackhuang.hmcl.mod.UnsupportedModpackException;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.setting.Settings;
|
import org.jackhuang.hmcl.setting.Settings;
|
||||||
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
|
import org.jackhuang.hmcl.task.Task;
|
||||||
|
import org.jackhuang.hmcl.task.TaskExecutor;
|
||||||
|
import org.jackhuang.hmcl.ui.construct.MessageBox;
|
||||||
|
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
||||||
|
import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane;
|
||||||
import org.jackhuang.hmcl.ui.download.DownloadWizardProvider;
|
import org.jackhuang.hmcl.ui.download.DownloadWizardProvider;
|
||||||
import org.jackhuang.hmcl.ui.wizard.DecoratorPage;
|
import org.jackhuang.hmcl.ui.wizard.DecoratorPage;
|
||||||
import org.jackhuang.hmcl.util.Lang;
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
import org.jackhuang.hmcl.util.OperatingSystem;
|
import org.jackhuang.hmcl.util.OperatingSystem;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -75,6 +85,7 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
|
|
||||||
private Node buildNode(Profile profile, String version, String game) {
|
private Node buildNode(Profile profile, String version, String game) {
|
||||||
VersionItem item = new VersionItem();
|
VersionItem item = new VersionItem();
|
||||||
|
item.setUpdate(profile.getRepository().isModpack(version));
|
||||||
item.setGameVersion(game);
|
item.setGameVersion(game);
|
||||||
item.setVersionName(version);
|
item.setVersionName(version);
|
||||||
item.setOnLaunchButtonClicked(e -> {
|
item.setOnLaunchButtonClicked(e -> {
|
||||||
@ -102,6 +113,29 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
Controllers.getDecorator().showPage(Controllers.getVersionPage());
|
Controllers.getDecorator().showPage(Controllers.getVersionPage());
|
||||||
Controllers.getVersionPage().load(version, profile);
|
Controllers.getVersionPage().load(version, profile);
|
||||||
});
|
});
|
||||||
|
item.setOnUpdateButtonClicked(event -> {
|
||||||
|
FileChooser chooser = new FileChooser();
|
||||||
|
chooser.setTitle(Main.i18n("modpack.choose"));
|
||||||
|
chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(Main.i18n("modpack"), "*.zip"));
|
||||||
|
File selectedFile = chooser.showOpenDialog(Controllers.getStage());
|
||||||
|
if (selectedFile != null) {
|
||||||
|
TaskExecutorDialogPane pane = new TaskExecutorDialogPane(null);
|
||||||
|
try {
|
||||||
|
TaskExecutor executor = ModpackHelper.getUpdateTask(profile, selectedFile, version, ModpackHelper.readModpackConfiguration(profile.getRepository().getModpackConfiguration(version)))
|
||||||
|
.then(Task.of(Schedulers.javafx(), Controllers::closeDialog)).executor();
|
||||||
|
pane.setExecutor(executor);
|
||||||
|
pane.setCurrentState(Main.i18n("modpack.update"));
|
||||||
|
executor.start();
|
||||||
|
Controllers.dialog(pane);
|
||||||
|
} catch (UnsupportedModpackException e) {
|
||||||
|
Controllers.dialog(Main.i18n("modpack.unsupported"), Main.i18n("message.error"), MessageBox.ERROR_MESSAGE);
|
||||||
|
} catch (MismatchedModpackTypeException e) {
|
||||||
|
Controllers.dialog(Main.i18n("modpack.mismatched_type"), Main.i18n("message.error"), MessageBox.ERROR_MESSAGE);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Controllers.dialog(Main.i18n("modpack.invalid"), Main.i18n("message.error"), MessageBox.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
File iconFile = profile.getRepository().getVersionIcon(version);
|
File iconFile = profile.getRepository().getVersionIcon(version);
|
||||||
if (iconFile.exists())
|
if (iconFile.exists())
|
||||||
item.setImage(new Image("file:" + iconFile.getAbsolutePath()));
|
item.setImage(new Image("file:" + iconFile.getAbsolutePath()));
|
||||||
|
@ -97,4 +97,28 @@ public final class SVG {
|
|||||||
return createSVGPath("M19,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H19A2,2 0 0,1 21,8H21L4,8V18L6.14,10H23.21L20.93,18.5C20.7,19.37 19.92,20 19,20Z", fill, width, height);
|
return createSVGPath("M19,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H19A2,2 0 0,1 21,8H21L4,8V18L6.14,10H23.21L20.93,18.5C20.7,19.37 19.92,20 19,20Z", fill, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Node update(String fill, double width, double height) {
|
||||||
|
return createSVGPath("M21,10.12H14.22L16.96,7.3C14.23,4.6 9.81,4.5 7.08,7.2C4.35,9.91 4.35,14.28 7.08,17C9.81,19.7 14.23,19.7 16.96,17C18.32,15.65 19,14.08 19,12.1H21C21,14.08 20.12,16.65 18.36,18.39C14.85,21.87 9.15,21.87 5.64,18.39C2.14,14.92 2.11,9.28 5.62,5.81C9.13,2.34 14.76,2.34 18.27,5.81L21,3V10.12M12.5,8V12.25L16,14.33L15.28,15.54L11,13V8H12.5Z", fill, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node close_circle(String fill, double width, double height) {
|
||||||
|
return createSVGPath("M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z", fill, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node check_circle(String fill, double width, double height) {
|
||||||
|
return createSVGPath("M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M11,16.5L18,9.5L16.59,8.09L11,13.67L7.91,10.59L6.5,12L11,16.5Z", fill, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node info_circle(String fill, double width, double height) {
|
||||||
|
return createSVGPath("M13,9H11V7H13M13,17H11V11H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z", fill, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node help_circle(String fill, double width, double height) {
|
||||||
|
return createSVGPath("M15.07,11.25L14.17,12.17C13.45,12.89 13,13.5 13,15H11V14.5C11,13.39 11.45,12.39 12.17,11.67L13.41,10.41C13.78,10.05 14,9.55 14,9C14,7.89 13.1,7 12,7A2,2 0 0,0 10,9H8A4,4 0 0,1 12,5A4,4 0 0,1 16,9C16,9.88 15.64,10.67 15.07,11.25M13,19H11V17H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z", fill, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node alert(String fill, double width, double height) {
|
||||||
|
return createSVGPath("M13,14H11V10H13M13,18H11V16H13M1,21H23L12,2L1,21Z", fill, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,8 @@ public final class VersionItem extends StackPane {
|
|||||||
@FXML
|
@FXML
|
||||||
private JFXButton btnSettings;
|
private JFXButton btnSettings;
|
||||||
@FXML
|
@FXML
|
||||||
|
private JFXButton btnUpdate;
|
||||||
|
@FXML
|
||||||
private JFXButton btnLaunch;
|
private JFXButton btnLaunch;
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton btnScript;
|
private JFXButton btnScript;
|
||||||
@ -67,10 +69,12 @@ public final class VersionItem extends StackPane {
|
|||||||
FXUtils.limitHeight(this, 156);
|
FXUtils.limitHeight(this, 156);
|
||||||
setEffect(new DropShadow(BlurType.GAUSSIAN, Color.rgb(0, 0, 0, 0.26), 5.0, 0.12, -1.0, 1.0));
|
setEffect(new DropShadow(BlurType.GAUSSIAN, Color.rgb(0, 0, 0, 0.26), 5.0, 0.12, -1.0, 1.0));
|
||||||
btnSettings.setGraphic(SVG.gear("black", 15, 15));
|
btnSettings.setGraphic(SVG.gear("black", 15, 15));
|
||||||
|
btnUpdate.setGraphic(SVG.update("black", 15, 15));
|
||||||
btnLaunch.setGraphic(SVG.launch("black", 15, 15));
|
btnLaunch.setGraphic(SVG.launch("black", 15, 15));
|
||||||
btnScript.setGraphic(SVG.script("black", 15, 15));
|
btnScript.setGraphic(SVG.script("black", 15, 15));
|
||||||
|
|
||||||
FXUtils.installTooltip(btnSettings, 0, 5000, 0, new Tooltip(Main.i18n("version.manage.settings")));
|
FXUtils.installTooltip(btnSettings, 0, 5000, 0, new Tooltip(Main.i18n("version.settings")));
|
||||||
|
FXUtils.installTooltip(btnUpdate, 0, 5000, 0, new Tooltip(Main.i18n("version.update")));
|
||||||
FXUtils.installTooltip(btnLaunch, 0, 5000, 0, new Tooltip(Main.i18n("version.launch")));
|
FXUtils.installTooltip(btnLaunch, 0, 5000, 0, new Tooltip(Main.i18n("version.launch")));
|
||||||
FXUtils.installTooltip(btnScript, 0, 5000, 0, new Tooltip(Main.i18n("version.launch_script")));
|
FXUtils.installTooltip(btnScript, 0, 5000, 0, new Tooltip(Main.i18n("version.launch_script")));
|
||||||
|
|
||||||
@ -84,6 +88,10 @@ public final class VersionItem extends StackPane {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setUpdate(boolean update) {
|
||||||
|
btnUpdate.setVisible(update);
|
||||||
|
}
|
||||||
|
|
||||||
public void setVersionName(String versionName) {
|
public void setVersionName(String versionName) {
|
||||||
lblVersionName.setText(versionName);
|
lblVersionName.setText(versionName);
|
||||||
}
|
}
|
||||||
@ -108,4 +116,8 @@ public final class VersionItem extends StackPane {
|
|||||||
launchClickedHandler = handler;
|
launchClickedHandler = handler;
|
||||||
btnLaunch.setOnMouseClicked(handler);
|
btnLaunch.setOnMouseClicked(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOnUpdateButtonClicked(EventHandler<? super MouseEvent> handler) {
|
||||||
|
btnUpdate.setOnMouseClicked(handler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,12 +112,12 @@ public final class VersionPage extends StackPane implements DecoratorPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onDelete() {
|
public void onDelete() {
|
||||||
if (FXUtils.alert(Alert.AlertType.CONFIRMATION, "Confirm", Main.i18n("version.manage.remove.confirm") + version)) {
|
Controllers.confirmDialog(Main.i18n("version.manage.remove.confirm", version), Main.i18n("message.confirm"), () -> {
|
||||||
if (profile.getRepository().removeVersionFromDisk(version)) {
|
if (profile.getRepository().removeVersionFromDisk(version)) {
|
||||||
profile.getRepository().refreshVersionsAsync().start();
|
profile.getRepository().refreshVersionsAsync().start();
|
||||||
Controllers.navigate(null);
|
Controllers.navigate(null);
|
||||||
}
|
}
|
||||||
}
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onExport() {
|
public void onExport() {
|
||||||
|
@ -85,6 +85,10 @@ public final class MessageBox {
|
|||||||
* Message Box Type: Question
|
* Message Box Type: Question
|
||||||
*/
|
*/
|
||||||
public static final int QUESTION_MESSAGE = 3;
|
public static final int QUESTION_MESSAGE = 3;
|
||||||
|
/**
|
||||||
|
* Message Box Type: Fine
|
||||||
|
*/
|
||||||
|
public static final int FINE_MESSAGE = 4;
|
||||||
/**
|
/**
|
||||||
* Message Box Type: Plain
|
* Message Box Type: Plain
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Hello Minecraft! Launcher.
|
* Hello Minecraft! Launcher.
|
||||||
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
|
* Copyright (C) 4017 huangyuhui <huanghongxun4008@126.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -21,8 +21,11 @@ import com.jfoenix.controls.JFXButton;
|
|||||||
import com.jfoenix.controls.JFXDialog;
|
import com.jfoenix.controls.JFXDialog;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
|
import org.jackhuang.hmcl.Main;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
|
import org.jackhuang.hmcl.ui.SVG;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@ -33,11 +36,17 @@ public final class MessageDialogPane extends StackPane {
|
|||||||
@FXML
|
@FXML
|
||||||
private JFXButton acceptButton;
|
private JFXButton acceptButton;
|
||||||
@FXML
|
@FXML
|
||||||
|
private JFXButton cancelButton;
|
||||||
|
@FXML
|
||||||
private Label content;
|
private Label content;
|
||||||
@FXML
|
@FXML
|
||||||
|
private Label graphic;
|
||||||
|
@FXML
|
||||||
private Label title;
|
private Label title;
|
||||||
|
@FXML
|
||||||
|
private HBox actions;
|
||||||
|
|
||||||
public MessageDialogPane(String text, String title, JFXDialog dialog, Runnable onAccept) {
|
public MessageDialogPane(String text, String title, JFXDialog dialog, int type, Runnable onAccept) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.dialog = dialog;
|
this.dialog = dialog;
|
||||||
|
|
||||||
@ -51,5 +60,39 @@ public final class MessageDialogPane extends StackPane {
|
|||||||
dialog.close();
|
dialog.close();
|
||||||
Optional.ofNullable(onAccept).ifPresent(Runnable::run);
|
Optional.ofNullable(onAccept).ifPresent(Runnable::run);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
actions.getChildren().remove(cancelButton);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case MessageBox.INFORMATION_MESSAGE:
|
||||||
|
graphic.setGraphic(SVG.info_circle("black", 40, 40));
|
||||||
|
break;
|
||||||
|
case MessageBox.ERROR_MESSAGE:
|
||||||
|
graphic.setGraphic(SVG.close_circle("black", 40, 40));
|
||||||
|
break;
|
||||||
|
case MessageBox.FINE_MESSAGE:
|
||||||
|
graphic.setGraphic(SVG.check_circle("black", 40, 40));
|
||||||
|
break;
|
||||||
|
case MessageBox.WARNING_MESSAGE:
|
||||||
|
graphic.setGraphic(SVG.alert("black", 40, 40));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageDialogPane(String text, String title, JFXDialog dialog, Runnable onAccept, Runnable onCancel) {
|
||||||
|
this(text, title, dialog, -1, onAccept);
|
||||||
|
|
||||||
|
cancelButton.setVisible(true);
|
||||||
|
cancelButton.setOnMouseClicked(e -> {
|
||||||
|
dialog.close();
|
||||||
|
Optional.ofNullable(onCancel).ifPresent(Runnable::run);
|
||||||
|
});
|
||||||
|
|
||||||
|
acceptButton.setText(Main.i18n("button.yes"));
|
||||||
|
cancelButton.setText(Main.i18n("button.no"));
|
||||||
|
|
||||||
|
actions.getChildren().add(cancelButton);
|
||||||
|
|
||||||
|
graphic.setGraphic(SVG.help_circle("black", 40, 40));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,9 @@ public class TaskExecutorDialogPane extends StackPane {
|
|||||||
FXUtils.limitHeight(this, 200);
|
FXUtils.limitHeight(this, 200);
|
||||||
FXUtils.limitWidth(this, 400);
|
FXUtils.limitWidth(this, 400);
|
||||||
|
|
||||||
|
if (cancel == null)
|
||||||
|
btnCancel.setDisable(true);
|
||||||
|
|
||||||
btnCancel.setOnMouseClicked(e -> {
|
btnCancel.setOnMouseClicked(e -> {
|
||||||
Optional.ofNullable(executor).ifPresent(TaskExecutor::cancel);
|
Optional.ofNullable(executor).ifPresent(TaskExecutor::cancel);
|
||||||
cancel.run();
|
cancel.run();
|
||||||
|
@ -62,18 +62,18 @@ public interface TaskExecutorDialogWizardDisplayer extends AbstractWizardDisplay
|
|||||||
@Override
|
@Override
|
||||||
public void onSucceed() {
|
public void onSucceed() {
|
||||||
if (settings.containsKey("success_message") && settings.get("success_message") instanceof String)
|
if (settings.containsKey("success_message") && settings.get("success_message") instanceof String)
|
||||||
JFXUtilities.runInFX(() -> Controllers.dialog((String) settings.get("success_message"), null, () -> Controllers.navigate(null)));
|
JFXUtilities.runInFX(() -> Controllers.dialog((String) settings.get("success_message"), null, MessageBox.FINE_MESSAGE, () -> Controllers.navigate(null)));
|
||||||
else if (!settings.containsKey("forbid_success_message"))
|
else if (!settings.containsKey("forbid_success_message"))
|
||||||
JFXUtilities.runInFX(() -> Controllers.dialog(Main.i18n("message.success"), null, () -> Controllers.navigate(null)));
|
JFXUtilities.runInFX(() -> Controllers.dialog(Main.i18n("message.success"), null, MessageBox.FINE_MESSAGE, () -> Controllers.navigate(null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTerminate() {
|
public void onTerminate() {
|
||||||
String appendix = StringUtils.getStackTrace(e.getLastException());
|
String appendix = StringUtils.getStackTrace(e.getLastException());
|
||||||
if (settings.containsKey("failure_message") && settings.get("failure_message") instanceof String)
|
if (settings.containsKey("failure_message") && settings.get("failure_message") instanceof String)
|
||||||
JFXUtilities.runInFX(() -> Controllers.dialog(appendix, (String) settings.get("failure_message"), () -> Controllers.navigate(null)));
|
JFXUtilities.runInFX(() -> Controllers.dialog(appendix, (String) settings.get("failure_message"), MessageBox.ERROR_MESSAGE, () -> Controllers.navigate(null)));
|
||||||
else if (!settings.containsKey("forbid_failure_message"))
|
else if (!settings.containsKey("forbid_failure_message"))
|
||||||
JFXUtilities.runInFX(() -> Controllers.dialog(appendix, Main.i18n("wizard.failed"), () -> Controllers.navigate(null)));
|
JFXUtilities.runInFX(() -> Controllers.dialog(appendix, Main.i18n("wizard.failed"), MessageBox.ERROR_MESSAGE, () -> Controllers.navigate(null)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
pane.setExecutor(executor);
|
pane.setExecutor(executor);
|
||||||
|
@ -83,9 +83,9 @@ public final class TaskListPane extends StackPane {
|
|||||||
} else if (task instanceof CurseInstallTask) {
|
} else if (task instanceof CurseInstallTask) {
|
||||||
task.setName(Main.i18n("modpack.install", Main.i18n("modpack.type.curse")));
|
task.setName(Main.i18n("modpack.install", Main.i18n("modpack.type.curse")));
|
||||||
} else if (task instanceof MultiMCModpackInstallTask) {
|
} else if (task instanceof MultiMCModpackInstallTask) {
|
||||||
task.setName(Main.i18n("modpack.install", Main.i18n("modpack.type.curse")));
|
task.setName(Main.i18n("modpack.install", Main.i18n("modpack.type.multimc")));
|
||||||
} else if (task instanceof HMCLModpackInstallTask) {
|
} else if (task instanceof HMCLModpackInstallTask) {
|
||||||
task.setName(Main.i18n("modpack.install", Main.i18n("modpack.type.curse")));
|
task.setName(Main.i18n("modpack.install", Main.i18n("modpack.type.hmcl")));
|
||||||
} else if (task instanceof HMCLModpackExportTask) {
|
} else if (task instanceof HMCLModpackExportTask) {
|
||||||
task.setName(Main.i18n("modpack.export"));
|
task.setName(Main.i18n("modpack.export"));
|
||||||
} else if (task instanceof MinecraftInstanceTask) {
|
} else if (task instanceof MinecraftInstanceTask) {
|
||||||
|
@ -82,7 +82,10 @@ public final class ModpackPage extends StackPane implements WizardPage {
|
|||||||
// TODO: original HMCL modpack support.
|
// TODO: original HMCL modpack support.
|
||||||
controller.getSettings().put(MODPACK_FILE, selectedFile);
|
controller.getSettings().put(MODPACK_FILE, selectedFile);
|
||||||
lblModpackLocation.setText(selectedFile.getAbsolutePath());
|
lblModpackLocation.setText(selectedFile.getAbsolutePath());
|
||||||
txtModpackName.getValidators().add(new Validator(Main.i18n("version.already_exists"), str -> !profile.getRepository().hasVersion(str) && StringUtils.isNotBlank(str)));
|
txtModpackName.getValidators().addAll(
|
||||||
|
new Validator(Main.i18n("install.new_game.already_exists"), str -> !profile.getRepository().hasVersion(str) && StringUtils.isNotBlank(str)),
|
||||||
|
new Validator(Main.i18n("version.forbidden_name"), str -> !profile.getRepository().forbidsVersion(str))
|
||||||
|
);
|
||||||
txtModpackName.textProperty().addListener(e -> btnInstall.setDisable(!txtModpackName.validate()));
|
txtModpackName.textProperty().addListener(e -> btnInstall.setDisable(!txtModpackName.validate()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -19,6 +19,7 @@ package org.jackhuang.hmcl.ui.export;
|
|||||||
|
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import org.jackhuang.hmcl.game.HMCLModpackExportTask;
|
import org.jackhuang.hmcl.game.HMCLModpackExportTask;
|
||||||
|
import org.jackhuang.hmcl.game.HMCLModpackManager;
|
||||||
import org.jackhuang.hmcl.mod.Modpack;
|
import org.jackhuang.hmcl.mod.Modpack;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||||
@ -28,8 +29,6 @@ import java.io.File;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.game.HMCLModpackManager.MODPACK_PREDICATE;
|
|
||||||
|
|
||||||
public final class ExportWizardProvider implements WizardProvider {
|
public final class ExportWizardProvider implements WizardProvider {
|
||||||
private final Profile profile;
|
private final Profile profile;
|
||||||
private final String version;
|
private final String version;
|
||||||
@ -60,7 +59,7 @@ public final class ExportWizardProvider implements WizardProvider {
|
|||||||
public Node createPage(WizardController controller, int step, Map<String, Object> settings) {
|
public Node createPage(WizardController controller, int step, Map<String, Object> settings) {
|
||||||
switch (step) {
|
switch (step) {
|
||||||
case 0: return new ModpackInfoPage(controller, version);
|
case 0: return new ModpackInfoPage(controller, version);
|
||||||
case 1: return new ModpackFileSelectionPage(controller, profile, version, MODPACK_PREDICATE);
|
case 1: return new ModpackFileSelectionPage(controller, profile, version, HMCLModpackManager::suggestMod);
|
||||||
default: throw new IllegalArgumentException("step");
|
default: throw new IllegalArgumentException("step");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
<JFXTextField fx:id="txtModpackName" labelFloat="true" promptText="%modpack.enter_name" StackPane.margin="$insets" />
|
<JFXTextField fx:id="txtModpackName" labelFloat="true" promptText="%modpack.enter_name" StackPane.margin="$insets" />
|
||||||
<BorderPane><left><Label text="%modpack.name"/></left><right><Label fx:id="lblName" /></right></BorderPane>
|
<BorderPane><left><Label text="%modpack.name"/></left><right><Label fx:id="lblName" /></right></BorderPane>
|
||||||
<BorderPane><left><Label text="%archive.version"/></left><right><Label fx:id="lblVersion" /></right></BorderPane>
|
<BorderPane><left><Label text="%archive.version"/></left><right><Label fx:id="lblVersion" /></right></BorderPane>
|
||||||
<BorderPane><left><Label text="Author"/></left><right><Label fx:id="lblAuthor" /></right></BorderPane>
|
<BorderPane><left><Label text="%archive.author"/></left><right><Label fx:id="lblAuthor" /></right></BorderPane>
|
||||||
<BorderPane>
|
<BorderPane>
|
||||||
<left><JFXButton fx:id="btnDescription" onMouseClicked="#onDescribe" text="%modpack.wizard.step.3" styleClass="jfx-button" /></left>
|
<left><JFXButton fx:id="btnDescription" onMouseClicked="#onDescribe" text="%modpack.wizard.step.3" styleClass="jfx-button" /></left>
|
||||||
<right><JFXButton buttonType="RAISED" fx:id="btnInstall" onMouseClicked="#onInstall" text="%button.install" styleClass="jfx-button-raised" /></right>
|
<right><JFXButton buttonType="RAISED" fx:id="btnInstall" onMouseClicked="#onInstall" text="%button.install" styleClass="jfx-button-raised" /></right>
|
||||||
|
@ -4,18 +4,25 @@
|
|||||||
<?import com.jfoenix.controls.JFXDialogLayout?>
|
<?import com.jfoenix.controls.JFXDialogLayout?>
|
||||||
<?import javafx.scene.control.Label?>
|
<?import javafx.scene.control.Label?>
|
||||||
<?import javafx.scene.layout.StackPane?>
|
<?import javafx.scene.layout.StackPane?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
<fx:root xmlns="http://javafx.com/javafx"
|
<fx:root xmlns="http://javafx.com/javafx"
|
||||||
xmlns:fx="http://javafx.com/fxml"
|
xmlns:fx="http://javafx.com/fxml"
|
||||||
type="StackPane">
|
type="StackPane">
|
||||||
|
<HBox spacing="8">
|
||||||
|
<Label fx:id="graphic" translateX="34" translateY="34" minWidth="40" maxWidth="40" minHeight="40" maxHeight="40" />
|
||||||
<JFXDialogLayout>
|
<JFXDialogLayout>
|
||||||
<heading>
|
<heading>
|
||||||
<Label fx:id="title" text="%message.info" />
|
<Label fx:id="title" text="%message.info" />
|
||||||
</heading>
|
</heading>
|
||||||
<body>
|
<body>
|
||||||
<Label fx:id="content" textAlignment="JUSTIFY" wrapText="true" />
|
<Label fx:id="content" wrapText="true" />
|
||||||
</body>
|
</body>
|
||||||
<actions>
|
<actions>
|
||||||
|
<HBox fx:id="actions">
|
||||||
<JFXButton fx:id="acceptButton" styleClass="dialog-accept" text="%button.ok" />
|
<JFXButton fx:id="acceptButton" styleClass="dialog-accept" text="%button.ok" />
|
||||||
|
<JFXButton fx:id="cancelButton" visible="false" styleClass="dialog-cancel" text="%button.cancel" />
|
||||||
|
</HBox>
|
||||||
</actions>
|
</actions>
|
||||||
</JFXDialogLayout>
|
</JFXDialogLayout>
|
||||||
|
</HBox>
|
||||||
</fx:root>
|
</fx:root>
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
<left>
|
<left>
|
||||||
<HBox spacing="8">
|
<HBox spacing="8">
|
||||||
<JFXButton fx:id="btnSettings" styleClass="toggle-icon4" maxWidth="30" maxHeight="30" minWidth="30" minHeight="30" prefWidth="30" prefHeight="30" />
|
<JFXButton fx:id="btnSettings" styleClass="toggle-icon4" maxWidth="30" maxHeight="30" minWidth="30" minHeight="30" prefWidth="30" prefHeight="30" />
|
||||||
|
<JFXButton fx:id="btnUpdate" styleClass="toggle-icon4" maxWidth="30" maxHeight="30" minWidth="30" minHeight="30" prefWidth="30" prefHeight="30" />
|
||||||
</HBox>
|
</HBox>
|
||||||
</left>
|
</left>
|
||||||
<right>
|
<right>
|
||||||
|
@ -110,7 +110,7 @@ profile.new=New Config
|
|||||||
|
|
||||||
button.refresh=Refresh
|
button.refresh=Refresh
|
||||||
version.launch=Play
|
version.launch=Play
|
||||||
version.manage.settings=Settings
|
version.settings=Settings
|
||||||
button.about=About
|
button.about=About
|
||||||
button.others=Others
|
button.others=Others
|
||||||
button.download=Download
|
button.download=Download
|
||||||
@ -211,7 +211,7 @@ modpack.wizard.step.1=Basic options
|
|||||||
modpack.wizard.step.1.title=Set the basic options to the modpack.
|
modpack.wizard.step.1.title=Set the basic options to the modpack.
|
||||||
modpack.wizard.step.initialization.include_launcher=Include the launcher
|
modpack.wizard.step.initialization.include_launcher=Include the launcher
|
||||||
modpack.wizard.step.initialization.exported_version=The exported game version
|
modpack.wizard.step.initialization.exported_version=The exported game version
|
||||||
modpack.wizard.step.initialization.save=Choose a location to export the game files to
|
modpack.wizard.step.initialization.save=Choose a path to export the game files to
|
||||||
modpack.wizard.step.initialization.warning=Before making modpack, you should ensure that your game can launch successfully,\nand that your Minecraft is release, not snapshot.\nand that it is not allowed to add mods which is not allowed to distribute to the modpack.
|
modpack.wizard.step.initialization.warning=Before making modpack, you should ensure that your game can launch successfully,\nand that your Minecraft is release, not snapshot.\nand that it is not allowed to add mods which is not allowed to distribute to the modpack.
|
||||||
modpack.wizard.step.2=Files selection
|
modpack.wizard.step.2=Files selection
|
||||||
modpack.wizard.step.2.title=Choose the files you want to put into the modpack.
|
modpack.wizard.step.2.title=Choose the files you want to put into the modpack.
|
||||||
@ -219,10 +219,8 @@ modpack.wizard.step.3=Description
|
|||||||
modpack.wizard.step.3.title=Describe your modpack.
|
modpack.wizard.step.3.title=Describe your modpack.
|
||||||
|
|
||||||
modpack.desc=Describe your modpack, including precautions, changlog, supporting Markdown(also supporting online pictures).
|
modpack.desc=Describe your modpack, including precautions, changlog, supporting Markdown(also supporting online pictures).
|
||||||
modpack.incorrect_format.no_json=The format of the modpack is incorrect, pack.json is missing.
|
|
||||||
modpack.incorrect_format.no_jar=The format of the modpack is incorrect, pack.json does not have attribute 'jar'
|
|
||||||
modpack.cannot_read_version=Failed to gather the game version
|
modpack.cannot_read_version=Failed to gather the game version
|
||||||
modpack.not_a_valid_location=Not a valid modpack location
|
modpack.not_a_valid_location=Not a valid modpack path
|
||||||
modpack.name=Modpack Name
|
modpack.name=Modpack Name
|
||||||
modpack.not_a_valid_name=Not a valid modpack name
|
modpack.not_a_valid_name=Not a valid modpack name
|
||||||
|
|
||||||
@ -308,7 +306,7 @@ version.game.old_alpha=Old Alpha
|
|||||||
version.manage.rename=Rename this version
|
version.manage.rename=Rename this version
|
||||||
version.manage.rename.message=Please enter the new name
|
version.manage.rename.message=Please enter the new name
|
||||||
version.manage.remove=Delete this version
|
version.manage.remove=Delete this version
|
||||||
version.manage.remove.confirm=Sure to remove the version
|
version.manage.remove.confirm=Sure to remove version %s?
|
||||||
version.manage.redownload_json=Redownload Minecraft Configuration(minecraft.json)
|
version.manage.redownload_json=Redownload Minecraft Configuration(minecraft.json)
|
||||||
version.manage.redownload_assets_index=Redownload Assets Index
|
version.manage.redownload_assets_index=Redownload Assets Index
|
||||||
version.manage.remove_libraries=Delete library files
|
version.manage.remove_libraries=Delete library files
|
||||||
@ -413,3 +411,10 @@ extension.png=Image file
|
|||||||
message.success=Tasks succeeded
|
message.success=Tasks succeeded
|
||||||
message.doing=Please wait
|
message.doing=Please wait
|
||||||
modpack.scan=Scanning this modpack
|
modpack.scan=Scanning this modpack
|
||||||
|
version.update=Update
|
||||||
|
modpack.unsupported=Unsupported modpack, only HMCL, MultiMC, Curse modpacks are supported.
|
||||||
|
modpack.mismatched_type=Mismatched modpack type, your current game is %s modpack, but your update file is %s modpack.
|
||||||
|
modpack.invalid=Invalid modpack file.
|
||||||
|
modpack.update=Upgrading game
|
||||||
|
message.confirm=Confirm
|
||||||
|
version.forbidden_name=Forbidden name, do not use this.
|
||||||
|
@ -110,7 +110,7 @@ profile.new=新建配置
|
|||||||
|
|
||||||
button.refresh=刷新
|
button.refresh=刷新
|
||||||
version.launch=启动游戏
|
version.launch=启动游戏
|
||||||
version.manage.settings=游戏设置
|
version.settings=游戏设置
|
||||||
button.about=关于
|
button.about=关于
|
||||||
button.others=其他
|
button.others=其他
|
||||||
button.download=下载
|
button.download=下载
|
||||||
@ -219,8 +219,6 @@ modpack.wizard.step.3=整合包描述
|
|||||||
modpack.wizard.step.3.title=描述你要制作的整合包
|
modpack.wizard.step.3.title=描述你要制作的整合包
|
||||||
|
|
||||||
modpack.desc=描述你要制作的整合包,比如整合包注意事项和更新记录,支持Markdown(图片请用网络图片)。
|
modpack.desc=描述你要制作的整合包,比如整合包注意事项和更新记录,支持Markdown(图片请用网络图片)。
|
||||||
modpack.incorrect_format.no_json=整合包格式错误,pack.json丢失
|
|
||||||
modpack.incorrect_format.no_jar=整合包格式错误,pack.json丢失jar字段
|
|
||||||
modpack.cannot_read_version=读取游戏版本失败
|
modpack.cannot_read_version=读取游戏版本失败
|
||||||
modpack.not_a_valid_location=不是一个有效整合包位置
|
modpack.not_a_valid_location=不是一个有效整合包位置
|
||||||
modpack.name=整合包名称
|
modpack.name=整合包名称
|
||||||
@ -308,7 +306,7 @@ version.game.old_alpha=远古版
|
|||||||
version.manage.rename=重命名该版本
|
version.manage.rename=重命名该版本
|
||||||
version.manage.rename.message=请输入要改成的名字
|
version.manage.rename.message=请输入要改成的名字
|
||||||
version.manage.remove=删除该版本
|
version.manage.remove=删除该版本
|
||||||
version.manage.remove.confirm=真的要删除版本
|
version.manage.remove.confirm=真的要删除版本 %s 吗?
|
||||||
version.manage.redownload_json=重新下载版本配置(minecraft.json)
|
version.manage.redownload_json=重新下载版本配置(minecraft.json)
|
||||||
version.manage.redownload_assets_index=重新下载资源配置(assets_index.json)
|
version.manage.redownload_assets_index=重新下载资源配置(assets_index.json)
|
||||||
version.manage.remove_libraries=删除所有库文件
|
version.manage.remove_libraries=删除所有库文件
|
||||||
@ -413,3 +411,10 @@ extension.png=图片文件
|
|||||||
message.success=已完成
|
message.success=已完成
|
||||||
message.doing=请耐心等待
|
message.doing=请耐心等待
|
||||||
modpack.scan=解析整合包
|
modpack.scan=解析整合包
|
||||||
|
version.update=更新
|
||||||
|
modpack.unsupported=该整合包不被支持。仅HMCL、MultiMC、Curse整合包受支持。
|
||||||
|
modpack.mismatched_type=整合包类型不匹配,当前游戏是 %s 整合包,但是提供的整合包更新文件是 %s 整合包。
|
||||||
|
modpack.invalid=无效的整合包升级文件,可能是下载时出现问题。
|
||||||
|
modpack.update=正在升级整合包
|
||||||
|
message.confirm=提示
|
||||||
|
version.forbidden_name=此版本名称不受支持,请换一个名字
|
||||||
|
4
HMCLCore/gradlew
vendored
4
HMCLCore/gradlew
vendored
@ -78,14 +78,14 @@ if [ -n "$JAVA_HOME" ] ; then
|
|||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
path of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD="java"
|
JAVACMD="java"
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
path of your Java installation."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
|
4
HMCLCore/gradlew.bat
vendored
4
HMCLCore/gradlew.bat
vendored
@ -27,7 +27,7 @@ echo.
|
|||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
echo.
|
echo.
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
echo location of your Java installation.
|
echo path of your Java installation.
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ echo.
|
|||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
echo.
|
echo.
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
echo location of your Java installation.
|
echo path of your Java installation.
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
|
@ -41,6 +41,14 @@ public class DefaultGameBuilder extends GameBuilder {
|
|||||||
this.downloadProvider = dependencyManager.getDownloadProvider();
|
this.downloadProvider = dependencyManager.getDownloadProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DefaultDependencyManager getDependencyManager() {
|
||||||
|
return dependencyManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadProvider getDownloadProvider() {
|
||||||
|
return downloadProvider;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task buildAsync() {
|
public Task buildAsync() {
|
||||||
return new VersionJsonDownloadTask(gameVersion, dependencyManager).then(variables -> {
|
return new VersionJsonDownloadTask(gameVersion, dependencyManager).then(variables -> {
|
||||||
@ -50,7 +58,7 @@ public class DefaultGameBuilder extends GameBuilder {
|
|||||||
Task result = new ParallelTask(
|
Task result = new ParallelTask(
|
||||||
new GameAssetDownloadTask(dependencyManager, version),
|
new GameAssetDownloadTask(dependencyManager, version),
|
||||||
new GameLoggingDownloadTask(dependencyManager, version),
|
new GameLoggingDownloadTask(dependencyManager, version),
|
||||||
new GameDownloadTask(dependencyManager, version),
|
downloadGameAsync(gameVersion, version),
|
||||||
new GameLibrariesTask(dependencyManager, version) // Game libraries will be downloaded for multiple times partly, this time is for vanilla libraries.
|
new GameLibrariesTask(dependencyManager, version) // Game libraries will be downloaded for multiple times partly, this time is for vanilla libraries.
|
||||||
).with(new VersionJsonSaveTask(dependencyManager.getGameRepository(), version)); // using [with] because download failure here are tolerant.
|
).with(new VersionJsonSaveTask(dependencyManager.getGameRepository(), version)); // using [with] because download failure here are tolerant.
|
||||||
|
|
||||||
@ -68,4 +76,8 @@ public class DefaultGameBuilder extends GameBuilder {
|
|||||||
return variables -> dependencyManager.installLibraryAsync(gameVersion, variables.get("version"), libraryId, toolVersions.get(libraryId));
|
return variables -> dependencyManager.installLibraryAsync(gameVersion, variables.get("version"), libraryId, toolVersions.get(libraryId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Task downloadGameAsync(String gameVersion, Version version) {
|
||||||
|
return new GameDownloadTask(dependencyManager, version);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -310,4 +310,12 @@ public class DefaultGameRepository implements GameRepository {
|
|||||||
return loaded;
|
return loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public File getModpackConfiguration(String version) {
|
||||||
|
return new File(getRunDirectory(version), "modpack.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isModpack(String version) {
|
||||||
|
return getModpackConfiguration(version).exists();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
|||||||
import org.jackhuang.hmcl.download.GameBuilder;
|
import org.jackhuang.hmcl.download.GameBuilder;
|
||||||
import org.jackhuang.hmcl.game.DefaultGameRepository;
|
import org.jackhuang.hmcl.game.DefaultGameRepository;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.util.CompressingUtils;
|
|
||||||
import org.jackhuang.hmcl.util.Constants;
|
import org.jackhuang.hmcl.util.Constants;
|
||||||
import org.jackhuang.hmcl.util.FileUtils;
|
import org.jackhuang.hmcl.util.FileUtils;
|
||||||
|
|
||||||
@ -32,7 +31,6 @@ import java.io.IOException;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Install a downloaded CurseForge modpack.
|
* Install a downloaded CurseForge modpack.
|
||||||
@ -68,7 +66,7 @@ public final class CurseInstallTask extends Task {
|
|||||||
this.repository = dependencyManager.getGameRepository();
|
this.repository = dependencyManager.getGameRepository();
|
||||||
this.run = repository.getRunDirectory(name);
|
this.run = repository.getRunDirectory(name);
|
||||||
|
|
||||||
File json = new File(run, "modpack.json");
|
File json = repository.getModpackConfiguration(name);
|
||||||
if (repository.hasVersion(name) && !json.exists())
|
if (repository.hasVersion(name) && !json.exists())
|
||||||
throw new IllegalArgumentException("Version " + name + " already exists.");
|
throw new IllegalArgumentException("Version " + name + " already exists.");
|
||||||
|
|
||||||
@ -80,8 +78,13 @@ public final class CurseInstallTask extends Task {
|
|||||||
|
|
||||||
ModpackConfiguration<CurseManifest> config = null;
|
ModpackConfiguration<CurseManifest> config = null;
|
||||||
try {
|
try {
|
||||||
if (json.exists())
|
if (json.exists()) {
|
||||||
config = Constants.GSON.fromJson(FileUtils.readText(json), new TypeToken<ModpackConfiguration<CurseManifest>>(){}.getType());
|
config = Constants.GSON.fromJson(FileUtils.readText(json), new TypeToken<ModpackConfiguration<CurseManifest>>() {
|
||||||
|
}.getType());
|
||||||
|
|
||||||
|
if (!MODPACK_TYPE.equals(config.getType()))
|
||||||
|
throw new IllegalArgumentException("Version " + name + " is not a Curse modpack. Cannot update this version.");
|
||||||
|
}
|
||||||
} catch (JsonParseException | IOException ignore) {
|
} catch (JsonParseException | IOException ignore) {
|
||||||
}
|
}
|
||||||
this.config = config;
|
this.config = config;
|
||||||
@ -110,7 +113,8 @@ public final class CurseInstallTask extends Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies.add(new CurseCompletionTask(dependencyManager, name));
|
dependencies.add(new CurseCompletionTask(dependencyManager, name));
|
||||||
dependencies.add(new MinecraftInstanceTask<>(zipFile, manifest.getOverrides(), false, manifest, new File(run, "modpack.json")));
|
dependencies.add(new MinecraftInstanceTask<>(zipFile, manifest.getOverrides(), manifest, MODPACK_TYPE, repository.getModpackConfiguration(name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final String MODPACK_TYPE = "Curse";
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,12 @@ import org.jackhuang.hmcl.task.Task;
|
|||||||
import org.jackhuang.hmcl.util.Constants;
|
import org.jackhuang.hmcl.util.Constants;
|
||||||
import org.jackhuang.hmcl.util.DigestUtils;
|
import org.jackhuang.hmcl.util.DigestUtils;
|
||||||
import org.jackhuang.hmcl.util.FileUtils;
|
import org.jackhuang.hmcl.util.FileUtils;
|
||||||
import org.jackhuang.hmcl.util.IOUtils;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public final class MinecraftInstanceTask<T> extends Task {
|
public final class MinecraftInstanceTask<T> extends Task {
|
||||||
@ -36,12 +37,14 @@ public final class MinecraftInstanceTask<T> extends Task {
|
|||||||
private final String subDirectory;
|
private final String subDirectory;
|
||||||
private final File jsonFile;
|
private final File jsonFile;
|
||||||
private final T manifest;
|
private final T manifest;
|
||||||
|
private final String type;
|
||||||
|
|
||||||
public MinecraftInstanceTask(File zipFile, String subDirectory, T manifest, File jsonFile) {
|
public MinecraftInstanceTask(File zipFile, String subDirectory, T manifest, String type, File jsonFile) {
|
||||||
this.zipFile = zipFile;
|
this.zipFile = zipFile;
|
||||||
this.subDirectory = subDirectory;
|
this.subDirectory = subDirectory;
|
||||||
this.manifest = manifest;
|
this.manifest = manifest;
|
||||||
this.jsonFile = jsonFile;
|
this.jsonFile = jsonFile;
|
||||||
|
this.type = type;
|
||||||
|
|
||||||
if (!zipFile.exists())
|
if (!zipFile.exists())
|
||||||
throw new IllegalArgumentException("File " + zipFile + " does not exist. Cannot parse this modpack.");
|
throw new IllegalArgumentException("File " + zipFile + " does not exist. Cannot parse this modpack.");
|
||||||
@ -49,9 +52,8 @@ public final class MinecraftInstanceTask<T> extends Task {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws Exception {
|
public void execute() throws Exception {
|
||||||
Map<String, ModpackConfiguration.FileInformation> overrides = new HashMap<>();
|
List<ModpackConfiguration.FileInformation> overrides = new LinkedList<>();
|
||||||
|
|
||||||
byte[] buf = new byte[IOUtils.DEFAULT_BUFFER_SIZE];
|
|
||||||
try (ZipArchiveInputStream zip = new ZipArchiveInputStream(new FileInputStream(zipFile), null, true, true)) {
|
try (ZipArchiveInputStream zip = new ZipArchiveInputStream(new FileInputStream(zipFile), null, true, true)) {
|
||||||
ArchiveEntry entry;
|
ArchiveEntry entry;
|
||||||
while ((entry = zip.getNextEntry()) != null) {
|
while ((entry = zip.getNextEntry()) != null) {
|
||||||
@ -62,12 +64,10 @@ public final class MinecraftInstanceTask<T> extends Task {
|
|||||||
if (path.startsWith("/") || path.startsWith("\\"))
|
if (path.startsWith("/") || path.startsWith("\\"))
|
||||||
path = path.substring(1);
|
path = path.substring(1);
|
||||||
|
|
||||||
overrides.put(path, new ModpackConfiguration.FileInformation(
|
overrides.add(new ModpackConfiguration.FileInformation(path, DigestUtils.sha1Hex(zip)));
|
||||||
path, DigestUtils.sha1Hex(zip)
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileUtils.writeText(jsonFile, Constants.GSON.toJson(new ModpackConfiguration<>(manifest, overrides)));
|
FileUtils.writeText(jsonFile, Constants.GSON.toJson(new ModpackConfiguration<>(manifest, type, overrides)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
|
||||||
|
*
|
||||||
|
* 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.mod;
|
||||||
|
|
||||||
|
public class MismatchedModpackTypeException extends Exception {
|
||||||
|
private final String required;
|
||||||
|
private final String found;
|
||||||
|
|
||||||
|
public MismatchedModpackTypeException(String required, String found) {
|
||||||
|
super("Required " + required + ", but found " + found);
|
||||||
|
|
||||||
|
this.required = required;
|
||||||
|
this.found = found;
|
||||||
|
}
|
||||||
|
}
|
@ -21,50 +21,56 @@ import com.google.gson.JsonParseException;
|
|||||||
import org.jackhuang.hmcl.util.Immutable;
|
import org.jackhuang.hmcl.util.Immutable;
|
||||||
import org.jackhuang.hmcl.util.Validation;
|
import org.jackhuang.hmcl.util.Validation;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
public final class ModpackConfiguration<T> implements Validation {
|
public final class ModpackConfiguration<T> implements Validation {
|
||||||
|
|
||||||
private final T manifest;
|
private final T manifest;
|
||||||
|
private final String type;
|
||||||
private final Map<String, FileInformation> overrides;
|
private final List<FileInformation> overrides;
|
||||||
|
|
||||||
public ModpackConfiguration() {
|
public ModpackConfiguration() {
|
||||||
this(null, Collections.emptyMap());
|
this(null, null, Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModpackConfiguration(T manifest, Map<String, FileInformation> overrides) {
|
public ModpackConfiguration(T manifest, String type, List<FileInformation> overrides) {
|
||||||
this.manifest = manifest;
|
this.manifest = manifest;
|
||||||
this.overrides = overrides;
|
this.type = type;
|
||||||
|
this.overrides = new ArrayList<>(overrides);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T getManifest() {
|
public T getManifest() {
|
||||||
return manifest;
|
return manifest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
public ModpackConfiguration<T> setManifest(T manifest) {
|
public ModpackConfiguration<T> setManifest(T manifest) {
|
||||||
return new ModpackConfiguration<>(manifest, overrides);
|
return new ModpackConfiguration<>(manifest, type, overrides);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModpackConfiguration<T> setOverrides(Map<String, FileInformation> overrides) {
|
public ModpackConfiguration<T> setOverrides(List<FileInformation> overrides) {
|
||||||
return new ModpackConfiguration<>(manifest, overrides);
|
return new ModpackConfiguration<>(manifest, type, overrides);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, FileInformation> getOverrides() {
|
public List<FileInformation> getOverrides() {
|
||||||
return Collections.unmodifiableMap(overrides);
|
return Collections.unmodifiableList(overrides);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validate() throws JsonParseException {
|
public void validate() throws JsonParseException {
|
||||||
if (manifest == null)
|
if (manifest == null)
|
||||||
throw new JsonParseException("MinecraftInstanceConfiguration missing `manifest`");
|
throw new JsonParseException("MinecraftInstanceConfiguration missing `manifest`");
|
||||||
|
if (type == null)
|
||||||
|
throw new JsonParseException("MinecraftInstanceConfiguration missing `type`");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
public static class FileInformation implements Validation {
|
public static class FileInformation implements Validation {
|
||||||
private final String location; // relative
|
private final String path; // relative
|
||||||
private final String hash;
|
private final String hash;
|
||||||
private final String downloadURL;
|
private final String downloadURL;
|
||||||
|
|
||||||
@ -72,18 +78,22 @@ public final class ModpackConfiguration<T> implements Validation {
|
|||||||
this(null, null);
|
this(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileInformation(String location, String hash) {
|
public FileInformation(String path, String hash) {
|
||||||
this(location, hash, null);
|
this(path, hash, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileInformation(String location, String hash, String downloadURL) {
|
public FileInformation(String path, String hash, String downloadURL) {
|
||||||
this.location = location;
|
this.path = path;
|
||||||
this.hash = hash;
|
this.hash = hash;
|
||||||
this.downloadURL = downloadURL;
|
this.downloadURL = downloadURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLocation() {
|
/**
|
||||||
return location;
|
* The relative path to Minecraft run directory
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getPath() {
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDownloadURL() {
|
public String getDownloadURL() {
|
||||||
@ -96,8 +106,8 @@ public final class ModpackConfiguration<T> implements Validation {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validate() throws JsonParseException {
|
public void validate() throws JsonParseException {
|
||||||
if (location == null)
|
if (path == null)
|
||||||
throw new JsonParseException("FileInformation missing `location`.");
|
throw new JsonParseException("FileInformation missing `path`.");
|
||||||
if (hash == null)
|
if (hash == null)
|
||||||
throw new JsonParseException("FileInformation missing file hash code.");
|
throw new JsonParseException("FileInformation missing file hash code.");
|
||||||
}
|
}
|
||||||
|
@ -25,10 +25,7 @@ import org.jackhuang.hmcl.util.FileUtils;
|
|||||||
import org.jackhuang.hmcl.util.IOUtils;
|
import org.jackhuang.hmcl.util.IOUtils;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class ModpackInstallTask<T> extends Task {
|
public class ModpackInstallTask<T> extends Task {
|
||||||
@ -36,7 +33,7 @@ public class ModpackInstallTask<T> extends Task {
|
|||||||
private final File modpackFile;
|
private final File modpackFile;
|
||||||
private final File dest;
|
private final File dest;
|
||||||
private final String subDirectory;
|
private final String subDirectory;
|
||||||
private final Map<String, ModpackConfiguration.FileInformation> overrides;
|
private final List<ModpackConfiguration.FileInformation> overrides;
|
||||||
private final Predicate<String> callback;
|
private final Predicate<String> callback;
|
||||||
|
|
||||||
public ModpackInstallTask(File modpackFile, File dest, String subDirectory, Predicate<String> callback, ModpackConfiguration<T> oldConfiguration) {
|
public ModpackInstallTask(File modpackFile, File dest, String subDirectory, Predicate<String> callback, ModpackConfiguration<T> oldConfiguration) {
|
||||||
@ -46,7 +43,7 @@ public class ModpackInstallTask<T> extends Task {
|
|||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
|
||||||
if (oldConfiguration == null)
|
if (oldConfiguration == null)
|
||||||
overrides = Collections.emptyMap();
|
overrides = Collections.emptyList();
|
||||||
else
|
else
|
||||||
overrides = oldConfiguration.getOverrides();
|
overrides = oldConfiguration.getOverrides();
|
||||||
}
|
}
|
||||||
@ -57,6 +54,11 @@ public class ModpackInstallTask<T> extends Task {
|
|||||||
byte[] buf = new byte[IOUtils.DEFAULT_BUFFER_SIZE];
|
byte[] buf = new byte[IOUtils.DEFAULT_BUFFER_SIZE];
|
||||||
if (!FileUtils.makeDirectory(dest))
|
if (!FileUtils.makeDirectory(dest))
|
||||||
throw new IOException("Unable to make directory " + dest);
|
throw new IOException("Unable to make directory " + dest);
|
||||||
|
|
||||||
|
HashSet<String> files = new HashSet<>();
|
||||||
|
for (ModpackConfiguration.FileInformation file : overrides)
|
||||||
|
files.add(file.getPath());
|
||||||
|
|
||||||
try (ZipArchiveInputStream zipStream = new ZipArchiveInputStream(new FileInputStream(modpackFile), null, true, true)) {
|
try (ZipArchiveInputStream zipStream = new ZipArchiveInputStream(new FileInputStream(modpackFile), null, true, true)) {
|
||||||
ArchiveEntry entry;
|
ArchiveEntry entry;
|
||||||
while ((entry = zipStream.getNextEntry()) != null) {
|
while ((entry = zipStream.getNextEntry()) != null) {
|
||||||
@ -86,7 +88,7 @@ public class ModpackInstallTask<T> extends Task {
|
|||||||
IOUtils.copyTo(zipStream, os, buf);
|
IOUtils.copyTo(zipStream, os, buf);
|
||||||
byte[] data = os.toByteArray();
|
byte[] data = os.toByteArray();
|
||||||
|
|
||||||
if (!overrides.containsKey(path) || entryFile.exists()) {
|
if (files.contains(path) && entryFile.exists()) {
|
||||||
String oldHash = DigestUtils.sha1Hex(new FileInputStream(entryFile));
|
String oldHash = DigestUtils.sha1Hex(new FileInputStream(entryFile));
|
||||||
String newHash = DigestUtils.sha1Hex(new ByteArrayInputStream(data));
|
String newHash = DigestUtils.sha1Hex(new ByteArrayInputStream(data));
|
||||||
if (!oldHash.equals(newHash)) {
|
if (!oldHash.equals(newHash)) {
|
||||||
@ -94,15 +96,19 @@ public class ModpackInstallTask<T> extends Task {
|
|||||||
IOUtils.copyTo(new ByteArrayInputStream(data), fos, buf);
|
IOUtils.copyTo(new ByteArrayInputStream(data), fos, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (!files.contains(path)) {
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(entryFile)) {
|
||||||
|
IOUtils.copyTo(new ByteArrayInputStream(data), fos, buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String path : overrides.keySet()) {
|
for (ModpackConfiguration.FileInformation file : overrides) {
|
||||||
File original = new File(dest, path);
|
File original = new File(dest, file.getPath());
|
||||||
if (original.exists() && !entries.contains(path))
|
if (original.exists() && !entries.contains(file.getPath()))
|
||||||
original.delete();
|
original.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ public final class MultiMCModpackInstallTask extends Task {
|
|||||||
this.repository = dependencyManager.getGameRepository();
|
this.repository = dependencyManager.getGameRepository();
|
||||||
this.run = repository.getRunDirectory(name);
|
this.run = repository.getRunDirectory(name);
|
||||||
|
|
||||||
File json = new File(run, "modpack.json");
|
File json = repository.getModpackConfiguration(name);
|
||||||
if (repository.hasVersion(name) && !json.exists())
|
if (repository.hasVersion(name) && !json.exists())
|
||||||
throw new IllegalArgumentException("Version " + name + " already exists.");
|
throw new IllegalArgumentException("Version " + name + " already exists.");
|
||||||
dependents.add(dependencyManager.gameBuilder().name(name).gameVersion(manifest.getGameVersion()).buildAsync());
|
dependents.add(dependencyManager.gameBuilder().name(name).gameVersion(manifest.getGameVersion()).buildAsync());
|
||||||
@ -69,8 +69,13 @@ public final class MultiMCModpackInstallTask extends Task {
|
|||||||
|
|
||||||
ModpackConfiguration<MultiMCInstanceConfiguration> config = null;
|
ModpackConfiguration<MultiMCInstanceConfiguration> config = null;
|
||||||
try {
|
try {
|
||||||
if (json.exists())
|
if (json.exists()) {
|
||||||
config = Constants.GSON.fromJson(FileUtils.readText(json), new TypeToken<ModpackConfiguration<MultiMCInstanceConfiguration>>(){}.getType());
|
config = Constants.GSON.fromJson(FileUtils.readText(json), new TypeToken<ModpackConfiguration<MultiMCInstanceConfiguration>>() {
|
||||||
|
}.getType());
|
||||||
|
|
||||||
|
if (!MODPACK_TYPE.equals(config.getType()))
|
||||||
|
throw new IllegalArgumentException("Version " + name + " is not a MultiMC modpack. Cannot update this version.");
|
||||||
|
}
|
||||||
} catch (JsonParseException | IOException ignore) {
|
} catch (JsonParseException | IOException ignore) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +115,8 @@ public final class MultiMCModpackInstallTask extends Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies.add(new VersionJsonSaveTask(repository, version));
|
dependencies.add(new VersionJsonSaveTask(repository, version));
|
||||||
dependencies.add(new MinecraftInstanceTask<>(zipFile, manifest.getName() + "/minecraft/", manifest, new File(run, "modpack.json")));
|
dependencies.add(new MinecraftInstanceTask<>(zipFile, manifest.getName() + "/minecraft/", manifest, MODPACK_TYPE, repository.getModpackConfiguration(name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final String MODPACK_TYPE = "MultiMC";
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
|
||||||
|
*
|
||||||
|
* 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.mod;
|
||||||
|
|
||||||
|
public class UnsupportedModpackException extends Exception {
|
||||||
|
public UnsupportedModpackException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnsupportedModpackException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnsupportedModpackException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnsupportedModpackException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
@ -114,7 +114,7 @@ public class FileDownloadTask extends Task {
|
|||||||
@Override
|
@Override
|
||||||
public void execute() throws Exception {
|
public void execute() throws Exception {
|
||||||
URL currentURL = url;
|
URL currentURL = url;
|
||||||
Logging.LOG.log(Level.FINER, "Downloading {0}, to {1}", new Object[] { currentURL, file });
|
Logging.LOG.log(Level.FINER, "Downloading {0} to {1}", new Object[] { currentURL, file });
|
||||||
Exception exception = null;
|
Exception exception = null;
|
||||||
|
|
||||||
for (int repeat = 0; repeat < retry; repeat++) {
|
for (int repeat = 0; repeat < retry; repeat++) {
|
||||||
@ -193,7 +193,7 @@ public class FileDownloadTask extends Task {
|
|||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (file.exists() || !file.delete())
|
if (file.exists() && !file.delete())
|
||||||
throw new IOException("Unable to delete existent file " + file);
|
throw new IOException("Unable to delete existent file " + file);
|
||||||
if (!FileUtils.makeDirectory(file.getAbsoluteFile().getParentFile()))
|
if (!FileUtils.makeDirectory(file.getAbsoluteFile().getParentFile()))
|
||||||
throw new IOException("Unable to make parent directory " + file);
|
throw new IOException("Unable to make parent directory " + file);
|
||||||
|
4
gradlew
vendored
4
gradlew
vendored
@ -78,14 +78,14 @@ if [ -n "$JAVA_HOME" ] ; then
|
|||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
path of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD="java"
|
JAVACMD="java"
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
path of your Java installation."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
|
4
gradlew.bat
vendored
4
gradlew.bat
vendored
@ -27,7 +27,7 @@ echo.
|
|||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
echo.
|
echo.
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
echo location of your Java installation.
|
echo path of your Java installation.
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ echo.
|
|||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
echo.
|
echo.
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
echo location of your Java installation.
|
echo path of your Java installation.
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user