Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63ca5dd409 | ||
|
|
663e1ef7ab | ||
|
|
1a47d355f0 | ||
|
|
e407994103 | ||
|
|
bda2149c02 | ||
|
|
b925423d61 | ||
|
|
f3906a37bf |
No files matched your search
@@ -31,7 +31,13 @@ import org.jackhuang.hmcl.upgrade.UpdateChecker;
|
||||
import org.jackhuang.hmcl.util.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
@@ -123,6 +129,25 @@ public final class Launcher extends Application {
|
||||
}
|
||||
}
|
||||
|
||||
public static List<File> getCurrentJarFiles() {
|
||||
List<File> result = new LinkedList<>();
|
||||
if (Launcher.class.getClassLoader() instanceof URLClassLoader) {
|
||||
URL[] urls = ((URLClassLoader) Launcher.class.getClassLoader()).getURLs();
|
||||
for (URL u : urls)
|
||||
try {
|
||||
File f = new File(u.toURI());
|
||||
if (f.isFile() && (f.getName().endsWith(".exe") || f.getName().endsWith(".jar")))
|
||||
result.add(f);
|
||||
} catch (URISyntaxException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (result.isEmpty())
|
||||
return null;
|
||||
else
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String i18n(String key) {
|
||||
try {
|
||||
return RESOURCE_BUNDLE.getString(key);
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.jackhuang.hmcl.util.JavaVersion;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
final class Config {
|
||||
public final class Config implements Cloneable {
|
||||
|
||||
@SerializedName("last")
|
||||
private String selectedProfile = "";
|
||||
@@ -97,7 +97,6 @@ final class Config {
|
||||
|
||||
public void setSelectedProfile(String selectedProfile) {
|
||||
this.selectedProfile = selectedProfile;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public String getBackgroundImage() {
|
||||
@@ -106,7 +105,6 @@ final class Config {
|
||||
|
||||
public void setBackgroundImage(String backgroundImage) {
|
||||
this.backgroundImage = backgroundImage;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public int getBackgroundImageType() {
|
||||
@@ -115,7 +113,6 @@ final class Config {
|
||||
|
||||
public void setBackgroundImageType(int backgroundImageType) {
|
||||
this.backgroundImageType = backgroundImageType;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public String getCommonDirectory() {
|
||||
@@ -124,7 +121,6 @@ final class Config {
|
||||
|
||||
public void setCommonDirectory(String commonDirectory) {
|
||||
this.commonDirectory = commonDirectory;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public boolean isHasProxy() {
|
||||
@@ -133,7 +129,6 @@ final class Config {
|
||||
|
||||
public void setHasProxy(boolean hasProxy) {
|
||||
this.hasProxy = hasProxy;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public boolean isHasProxyAuth() {
|
||||
@@ -142,7 +137,6 @@ final class Config {
|
||||
|
||||
public void setHasProxyAuth(boolean hasProxyAuth) {
|
||||
this.hasProxyAuth = hasProxyAuth;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public int getProxyType() {
|
||||
@@ -151,7 +145,6 @@ final class Config {
|
||||
|
||||
public void setProxyType(int proxyType) {
|
||||
this.proxyType = proxyType;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public String getProxyHost() {
|
||||
@@ -160,7 +153,6 @@ final class Config {
|
||||
|
||||
public void setProxyHost(String proxyHost) {
|
||||
this.proxyHost = proxyHost;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public String getProxyPort() {
|
||||
@@ -169,7 +161,6 @@ final class Config {
|
||||
|
||||
public void setProxyPort(String proxyPort) {
|
||||
this.proxyPort = proxyPort;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public String getProxyUser() {
|
||||
@@ -178,7 +169,6 @@ final class Config {
|
||||
|
||||
public void setProxyUser(String proxyUser) {
|
||||
this.proxyUser = proxyUser;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public String getProxyPass() {
|
||||
@@ -187,7 +177,6 @@ final class Config {
|
||||
|
||||
public void setProxyPass(String proxyPass) {
|
||||
this.proxyPass = proxyPass;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public String getTheme() {
|
||||
@@ -196,7 +185,6 @@ final class Config {
|
||||
|
||||
public void setTheme(String theme) {
|
||||
this.theme = theme;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public List<JavaVersion> getJava() {
|
||||
@@ -205,7 +193,6 @@ final class Config {
|
||||
|
||||
public void setJava(List<JavaVersion> java) {
|
||||
this.java = java;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public String getLocalization() {
|
||||
@@ -214,7 +201,6 @@ final class Config {
|
||||
|
||||
public void setLocalization(String localization) {
|
||||
this.localization = localization;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public int getDownloadType() {
|
||||
@@ -223,7 +209,6 @@ final class Config {
|
||||
|
||||
public void setDownloadType(int downloadType) {
|
||||
this.downloadType = downloadType;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public Map<String, Profile> getConfigurations() {
|
||||
@@ -232,7 +217,6 @@ final class Config {
|
||||
|
||||
public void setConfigurations(Map<String, Profile> configurations) {
|
||||
this.configurations = configurations;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public List<Map<Object, Object>> getAccounts() {
|
||||
@@ -241,7 +225,6 @@ final class Config {
|
||||
|
||||
public void setAccounts(List<Map<Object, Object>> accounts) {
|
||||
this.accounts = accounts;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public String getSelectedAccount() {
|
||||
@@ -250,7 +233,6 @@ final class Config {
|
||||
|
||||
public void setSelectedAccount(String selectedAccount) {
|
||||
this.selectedAccount = selectedAccount;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public String getFontFamily() {
|
||||
@@ -259,7 +241,6 @@ final class Config {
|
||||
|
||||
public void setFontFamily(String fontFamily) {
|
||||
this.fontFamily = fontFamily;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public double getFontSize() {
|
||||
@@ -268,7 +249,6 @@ final class Config {
|
||||
|
||||
public void setFontSize(double fontSize) {
|
||||
this.fontSize = fontSize;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public int getLogLines() {
|
||||
@@ -285,6 +265,9 @@ final class Config {
|
||||
|
||||
public void setAuthlibInjectorServerURLs(Set<String> authlibInjectorServerURLs) {
|
||||
this.authlibInjectorServerURLs = authlibInjectorServerURLs;
|
||||
Settings.INSTANCE.save();
|
||||
}
|
||||
|
||||
public Config clone() {
|
||||
return Settings.GSON.fromJson(Settings.GSON.toJson(this), Config.class);
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,8 @@ public class Settings {
|
||||
public static final String DEFAULT_PROFILE = "Default";
|
||||
public static final String HOME_PROFILE = "Home";
|
||||
|
||||
public static final File SETTINGS_FILE = new File("hmcl.json").getAbsoluteFile();
|
||||
public static final String SETTINGS_FILE_NAME = "hmcl.json";
|
||||
public static final File SETTINGS_FILE = new File(SETTINGS_FILE_NAME).getAbsoluteFile();
|
||||
|
||||
public static final Settings INSTANCE = new Settings();
|
||||
|
||||
@@ -144,6 +145,7 @@ public class Settings {
|
||||
super.invalidated();
|
||||
|
||||
SETTINGS.setCommonDirectory(get());
|
||||
save();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -168,6 +170,7 @@ public class Settings {
|
||||
public void setLocale(Locales.SupportedLocale locale) {
|
||||
this.locale = locale;
|
||||
SETTINGS.setLocalization(Locales.getNameByLocale(locale));
|
||||
save();
|
||||
}
|
||||
|
||||
private Proxy proxy = Proxy.NO_PROXY;
|
||||
@@ -185,6 +188,7 @@ public class Settings {
|
||||
public void setProxyType(Proxy.Type proxyType) {
|
||||
this.proxyType = proxyType;
|
||||
SETTINGS.setProxyType(Proxies.PROXIES.indexOf(proxyType));
|
||||
save();
|
||||
loadProxy();
|
||||
}
|
||||
|
||||
@@ -194,6 +198,7 @@ public class Settings {
|
||||
|
||||
public void setProxyHost(String proxyHost) {
|
||||
SETTINGS.setProxyHost(proxyHost);
|
||||
save();
|
||||
}
|
||||
|
||||
public String getProxyPort() {
|
||||
@@ -202,6 +207,7 @@ public class Settings {
|
||||
|
||||
public void setProxyPort(String proxyPort) {
|
||||
SETTINGS.setProxyPort(proxyPort);
|
||||
save();
|
||||
}
|
||||
|
||||
public String getProxyUser() {
|
||||
@@ -210,6 +216,7 @@ public class Settings {
|
||||
|
||||
public void setProxyUser(String proxyUser) {
|
||||
SETTINGS.setProxyUser(proxyUser);
|
||||
save();
|
||||
}
|
||||
|
||||
public String getProxyPass() {
|
||||
@@ -218,15 +225,22 @@ public class Settings {
|
||||
|
||||
public void setProxyPass(String proxyPass) {
|
||||
SETTINGS.setProxyPass(proxyPass);
|
||||
save();
|
||||
}
|
||||
|
||||
public boolean hasProxy() { return SETTINGS.isHasProxy(); }
|
||||
|
||||
public void setHasProxy(boolean hasProxy) { SETTINGS.setHasProxy(hasProxy); }
|
||||
public void setHasProxy(boolean hasProxy) {
|
||||
SETTINGS.setHasProxy(hasProxy);
|
||||
save();
|
||||
}
|
||||
|
||||
public boolean hasProxyAuth() { return SETTINGS.isHasProxyAuth(); }
|
||||
|
||||
public void setHasProxyAuth(boolean hasProxyAuth) { SETTINGS.setHasProxyAuth(hasProxyAuth); }
|
||||
public void setHasProxyAuth(boolean hasProxyAuth) {
|
||||
SETTINGS.setHasProxyAuth(hasProxyAuth);
|
||||
save();
|
||||
}
|
||||
|
||||
private void loadProxy() {
|
||||
String host = getProxyHost();
|
||||
@@ -261,6 +275,7 @@ public class Settings {
|
||||
public void setFont(Font font) {
|
||||
SETTINGS.setFontFamily(font.getFamily());
|
||||
SETTINGS.setFontSize(font.getSize());
|
||||
save();
|
||||
}
|
||||
|
||||
public int getLogLines() {
|
||||
@@ -269,6 +284,7 @@ public class Settings {
|
||||
|
||||
public void setLogLines(int logLines) {
|
||||
SETTINGS.setLogLines(logLines);
|
||||
save();
|
||||
}
|
||||
|
||||
/****************************************
|
||||
@@ -296,8 +312,10 @@ public class Settings {
|
||||
}
|
||||
|
||||
private void checkAuthlibInjectorServerURLs() {
|
||||
if (SETTINGS.getAuthlibInjectorServerURLs() == null)
|
||||
if (SETTINGS.getAuthlibInjectorServerURLs() == null) {
|
||||
SETTINGS.setAuthlibInjectorServerURLs(new HashSet<>());
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAuthlibInjectorAccounts() {
|
||||
@@ -323,6 +341,7 @@ public class Settings {
|
||||
if (index == -1)
|
||||
throw new IllegalArgumentException("Unknown download provider: " + downloadProvider);
|
||||
SETTINGS.setDownloadType(index);
|
||||
save();
|
||||
}
|
||||
|
||||
/****************************************
|
||||
@@ -352,6 +371,7 @@ public class Settings {
|
||||
super.invalidated();
|
||||
|
||||
SETTINGS.setSelectedAccount(getValue() == null ? "" : Accounts.getAccountId(getValue()));
|
||||
save();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -404,6 +424,7 @@ public class Settings {
|
||||
super.invalidated();
|
||||
|
||||
SETTINGS.setBackgroundImage(get());
|
||||
save();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -425,6 +446,7 @@ public class Settings {
|
||||
super.invalidated();
|
||||
|
||||
SETTINGS.setBackgroundImageType(get().ordinal());
|
||||
save();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -450,6 +472,7 @@ public class Settings {
|
||||
super.invalidated();
|
||||
|
||||
SETTINGS.setTheme(get().getName().toLowerCase());
|
||||
save();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -473,7 +496,10 @@ public class Settings {
|
||||
checkProfileMap();
|
||||
|
||||
if (!hasProfile(SETTINGS.getSelectedProfile())) {
|
||||
getProfileMap().keySet().stream().findFirst().ifPresent(SETTINGS::setSelectedProfile);
|
||||
getProfileMap().keySet().stream().findFirst().ifPresent(selectedProfile -> {
|
||||
SETTINGS.setSelectedProfile(selectedProfile);
|
||||
save();
|
||||
});
|
||||
Schedulers.computation().schedule(this::onProfileChanged);
|
||||
}
|
||||
return getProfile(SETTINGS.getSelectedProfile());
|
||||
@@ -482,6 +508,7 @@ public class Settings {
|
||||
public void setSelectedProfile(Profile selectedProfile) {
|
||||
if (hasProfile(selectedProfile.getName()) && !Objects.equals(selectedProfile.getName(), SETTINGS.getSelectedProfile())) {
|
||||
SETTINGS.setSelectedProfile(selectedProfile.getName());
|
||||
save();
|
||||
Schedulers.computation().schedule(this::onProfileChanged);
|
||||
}
|
||||
}
|
||||
@@ -555,4 +582,8 @@ public class Settings {
|
||||
public void onAccountLoading() {
|
||||
EventBus.EVENT_BUS.fireEvent(new AccountLoadingEvent(this, getAccounts()));
|
||||
}
|
||||
|
||||
public Config getRawConfig() {
|
||||
return SETTINGS.clone();
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
||||
import org.jackhuang.hmcl.ui.animation.TransitionHandler;
|
||||
import org.jackhuang.hmcl.ui.construct.URLValidator;
|
||||
import org.jackhuang.hmcl.ui.wizard.DecoratorPage;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.NetworkUtils;
|
||||
@@ -45,6 +46,9 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa
|
||||
@FXML private JFXProgressBar progressBar;
|
||||
@FXML private JFXButton btnAddNext;
|
||||
|
||||
@FXML private URLValidator validatorURL;
|
||||
@FXML private URLValidator validatorHttp;
|
||||
|
||||
private final TransitionHandler transitionHandler;
|
||||
|
||||
{
|
||||
@@ -55,6 +59,9 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa
|
||||
getChildren().remove(dialog);
|
||||
dialog.setDialogContainer(this);
|
||||
|
||||
validatorURL.setMessage(Launcher.i18n("input.url"));
|
||||
validatorHttp.setMessage(Launcher.i18n("input.url.http"));
|
||||
|
||||
txtServerIp.textProperty().addListener((a, b, newValue) ->
|
||||
btnAddNext.setDisable(!txtServerIp.validate()));
|
||||
|
||||
|
||||
@@ -195,10 +195,10 @@ public final class LeftPaneController {
|
||||
}
|
||||
|
||||
private boolean checkedModpack = false;
|
||||
private static boolean showNewAccount = true;
|
||||
|
||||
private void onRefreshedVersions(RefreshedVersionsEvent event) {
|
||||
JFXUtilities.runInFX(() -> {
|
||||
boolean flag = true;
|
||||
HMCLGameRepository repository = (HMCLGameRepository) event.getSource();
|
||||
if (!checkedModpack) {
|
||||
checkedModpack = true;
|
||||
@@ -216,15 +216,17 @@ public final class LeftPaneController {
|
||||
})).executor();
|
||||
region.set(Controllers.taskDialog(executor, Launcher.i18n("modpack.installing"), ""));
|
||||
executor.start();
|
||||
flag = false;
|
||||
showNewAccount = false;
|
||||
} catch (UnsupportedModpackException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
if (showNewAccount) {
|
||||
showNewAccount = false;
|
||||
checkAccount();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -17,10 +17,6 @@ public class URLValidator extends ValidatorBase {
|
||||
super();
|
||||
}
|
||||
|
||||
public URLValidator(@NamedArg("message") String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ObservableList<String> getProtocols() {
|
||||
return protocols;
|
||||
}
|
||||
|
||||
@@ -18,14 +18,23 @@
|
||||
package org.jackhuang.hmcl.ui.export;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import org.jackhuang.hmcl.Launcher;
|
||||
import org.jackhuang.hmcl.game.HMCLModpackExportTask;
|
||||
import org.jackhuang.hmcl.game.HMCLModpackManager;
|
||||
import org.jackhuang.hmcl.mod.Modpack;
|
||||
import org.jackhuang.hmcl.setting.Config;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
||||
import org.jackhuang.hmcl.util.Constants;
|
||||
import org.jackhuang.hmcl.util.ZipEngine;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -46,16 +55,73 @@ public final class ExportWizardProvider implements WizardProvider {
|
||||
public Object finish(Map<String, Object> settings) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> whitelist = (List<String>) settings.get(ModpackFileSelectionPage.MODPACK_FILE_SELECTION);
|
||||
List<File> launcherJar = Launcher.getCurrentJarFiles();
|
||||
boolean includeLauncher = (Boolean) settings.get(ModpackInfoPage.MODPACK_INCLUDE_LAUNCHER) && launcherJar != null;
|
||||
|
||||
return new HMCLModpackExportTask(profile.getRepository(), version, whitelist,
|
||||
new Modpack(
|
||||
(String) settings.get(ModpackInfoPage.MODPACK_NAME),
|
||||
(String) settings.get(ModpackInfoPage.MODPACK_AUTHOR),
|
||||
(String) settings.get(ModpackInfoPage.MODPACK_VERSION),
|
||||
null,
|
||||
(String) settings.get(ModpackInfoPage.MODPACK_DESCRIPTION),
|
||||
null
|
||||
), (File) settings.get(ModpackInfoPage.MODPACK_FILE));
|
||||
return new Task() {
|
||||
Task dependency = null;
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
File modpackFile = (File) settings.get(ModpackInfoPage.MODPACK_FILE);
|
||||
File tempModpack = includeLauncher ? Files.createTempFile("hmcl", ".zip").toFile() : modpackFile;
|
||||
|
||||
dependency = new HMCLModpackExportTask(profile.getRepository(), version, whitelist,
|
||||
new Modpack(
|
||||
(String) settings.get(ModpackInfoPage.MODPACK_NAME),
|
||||
(String) settings.get(ModpackInfoPage.MODPACK_AUTHOR),
|
||||
(String) settings.get(ModpackInfoPage.MODPACK_VERSION),
|
||||
null,
|
||||
(String) settings.get(ModpackInfoPage.MODPACK_DESCRIPTION),
|
||||
null
|
||||
), tempModpack);
|
||||
|
||||
if (includeLauncher) {
|
||||
dependency = dependency.then(Task.of(() -> {
|
||||
boolean flag = true;
|
||||
|
||||
try (ZipEngine zip = new ZipEngine(modpackFile)) {
|
||||
Config config = Settings.INSTANCE.getRawConfig();
|
||||
|
||||
config.setHasProxy(false);
|
||||
config.setSelectedProfile("");
|
||||
config.setCommonDirectory(null);
|
||||
config.setFontFamily("Consolas");
|
||||
config.setFontSize(12);
|
||||
config.setJava(null);
|
||||
config.setLocalization(null);
|
||||
config.setAccounts(null);
|
||||
config.setSelectedAccount("");
|
||||
config.setLogLines(100);
|
||||
config.setConfigurations(null);
|
||||
|
||||
zip.putTextFile(Settings.GSON.toJson(config), Settings.SETTINGS_FILE_NAME);
|
||||
zip.putFile(tempModpack, "modpack.zip");
|
||||
|
||||
File bg = new File("bg").getAbsoluteFile();
|
||||
if (bg.isDirectory())
|
||||
zip.putDirectory(bg);
|
||||
|
||||
File background_png = new File("background.png").getAbsoluteFile();
|
||||
if (background_png.isFile())
|
||||
zip.putFile(background_png, "background.png");
|
||||
|
||||
File background_jpg = new File("background.jpg").getAbsoluteFile();
|
||||
if (background_jpg.isFile())
|
||||
zip.putFile(background_jpg, "background.jpg");
|
||||
|
||||
for (File jar : launcherJar)
|
||||
zip.putFile(jar, jar.getName());
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends Task> getDependencies() {
|
||||
return Collections.singleton(dependency);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -33,8 +33,10 @@ import org.jackhuang.hmcl.ui.Controllers;
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
||||
import org.jackhuang.hmcl.util.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -45,12 +47,16 @@ public final class ModpackInfoPage extends StackPane implements WizardPage {
|
||||
@FXML
|
||||
private JFXTextField txtModpackName;
|
||||
@FXML
|
||||
private JFXTextField txtModpackAuthor;@FXML
|
||||
private JFXTextField txtModpackVersion;@FXML
|
||||
private JFXTextField txtModpackAuthor;
|
||||
@FXML
|
||||
private JFXTextField txtModpackVersion;
|
||||
@FXML
|
||||
private JFXTextArea txtModpackDescription;
|
||||
@FXML
|
||||
private JFXToggleButton chkIncludeLauncher;@FXML
|
||||
private JFXButton btnNext;@FXML
|
||||
private JFXToggleButton chkIncludeLauncher;
|
||||
@FXML
|
||||
private JFXButton btnNext;
|
||||
@FXML
|
||||
private ScrollPane scroll;
|
||||
|
||||
public ModpackInfoPage(WizardController controller, String version) {
|
||||
@@ -63,6 +69,10 @@ public final class ModpackInfoPage extends StackPane implements WizardPage {
|
||||
txtModpackVersion.textProperty().addListener(e -> checkValidation());
|
||||
txtModpackAuthor.setText(Optional.ofNullable(Settings.INSTANCE.getSelectedAccount()).map(Account::getUsername).orElse(""));
|
||||
lblVersionName.setText(version);
|
||||
|
||||
List<File> launcherJar = Launcher.getCurrentJarFiles();
|
||||
if (launcherJar == null)
|
||||
chkIncludeLauncher.setDisable(true);
|
||||
}
|
||||
|
||||
private void checkValidation() {
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
<body>
|
||||
<JFXTextField fx:id="txtServerIp" promptText="%account.injector.server_ip">
|
||||
<validators>
|
||||
<URLValidator message="%input.url">
|
||||
<URLValidator fx:id="validatorURL">
|
||||
</URLValidator>
|
||||
<URLValidator message="%input.url.http">
|
||||
<URLValidator fx:id="validatorHttp">
|
||||
<protocols>
|
||||
<String fx:value="http" />
|
||||
<String fx:value="https" />
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</right>
|
||||
</BorderPane>
|
||||
|
||||
<FileItem fx:id="gameDir" name="%profile.instance_directory" title="%settings.choose_gamedir"/>
|
||||
<FileItem fx:id="gameDir" name="%profile.instance_directory" title="%profile.instance_directory.choose"/>
|
||||
</ComponentList>
|
||||
|
||||
</VBox>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<MultiFileItem fx:id="javaItem" title="%settings.game.java_directory" chooserTitle="%settings.game.java_directory.choose"
|
||||
hasSubtitle="true" customText="%settings.custom" directory="false" />
|
||||
|
||||
<MultiFileItem fx:id="gameDirItem" title="%profile.instance_directory" chooserTitle="%settings.choose_gamedir"
|
||||
<MultiFileItem fx:id="gameDirItem" title="%settings.game.game_directory" chooserTitle="%settings.game.game_directory.choose"
|
||||
hasSubtitle="true" customText="%settings.custom" directory="true" />
|
||||
|
||||
<BorderPane> <!-- Max Memory -->
|
||||
|
||||
@@ -311,6 +311,7 @@ profile=Profile
|
||||
profile.default=Current directory
|
||||
profile.home=User home
|
||||
profile.instance_directory=Game Directory
|
||||
profile.instance_directory.choose=Choose Game Directory
|
||||
profile.new=New Config
|
||||
profile.new_name=New Profile Name:
|
||||
profile.remove=Sure to remove profile %s?
|
||||
@@ -343,7 +344,6 @@ settings.advanced.server_ip=Server Host
|
||||
settings.advanced.wrapper_launcher=Wrapper Launcher(i.e. optirun...)
|
||||
|
||||
settings.cannot_remove_default_config=Cannot remove the default configution.
|
||||
settings.choose_gamedir=Choose Game Directory
|
||||
settings.custom=Custom
|
||||
settings.default=Default
|
||||
settings.failed_load=Failed to load settings file. Remove it?
|
||||
@@ -352,6 +352,8 @@ settings.game=Games
|
||||
settings.game.dimension=Game Window Dimension
|
||||
settings.game.exploration=Explore
|
||||
settings.game.fullscreen=Fullscreen
|
||||
settings.game.game_directory=Game Directory
|
||||
settings.game.game_directory.choose=Choose Game Directory
|
||||
settings.game.java_directory=Java Dir
|
||||
settings.game.java_directory.choose=Choose Java Directory.
|
||||
settings.game.management=Manage
|
||||
|
||||
@@ -147,7 +147,7 @@ install.installer.forge=Forge
|
||||
install.installer.game=游戏
|
||||
install.installer.install=安装%s
|
||||
install.installer.liteloader=LiteLoader
|
||||
install.installer.not_installed=不安装%s
|
||||
install.installer.not_installed=暂不安装%s,可以点击此处安装
|
||||
install.installer.optifine=OptiFine
|
||||
install.installer.version=%s版本
|
||||
install.modpack=安装整合包
|
||||
@@ -311,6 +311,7 @@ profile=配置
|
||||
profile.default=当前目录
|
||||
profile.home=主文件夹
|
||||
profile.instance_directory=游戏路径
|
||||
profile.instance_directory.choose=选择游戏路径
|
||||
profile.new=新建配置
|
||||
profile.new_name=新配置名:
|
||||
profile.remove=真的要删除配置%s吗?
|
||||
@@ -343,7 +344,6 @@ settings.advanced.server_ip=直入服务器ip地址(不必填写,启动游戏
|
||||
settings.advanced.wrapper_launcher=前置指令(不必填写,如optirun)
|
||||
|
||||
settings.cannot_remove_default_config=不能删除默认配置
|
||||
settings.choose_gamedir=选择游戏路径
|
||||
settings.custom=自定义
|
||||
settings.default=默认
|
||||
settings.failed_load=设置文件加载失败,可能是升级了启动器或被人工修改造成错误,是否清除?
|
||||
@@ -352,6 +352,8 @@ settings.game=游戏设置
|
||||
settings.game.dimension=游戏窗口分辨率
|
||||
settings.game.exploration=浏览
|
||||
settings.game.fullscreen=全屏
|
||||
settings.game.game_directory=游戏路径(版本隔离)
|
||||
settings.game.game_directory.choose=选择游戏路径
|
||||
settings.game.java_directory=Java路径
|
||||
settings.game.java_directory.choose=选择Java路径
|
||||
settings.game.management=管理
|
||||
|
||||
@@ -36,27 +36,27 @@ public class BMCLAPIDownloadProvider implements DownloadProvider {
|
||||
|
||||
@Override
|
||||
public String getLibraryBaseURL() {
|
||||
return "http://bmclapi2.bangbang93.com/libraries/";
|
||||
return "https://bmclapi2.bangbang93.com/libraries/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionListURL() {
|
||||
return "http://bmclapi2.bangbang93.com/mc/game/version_manifest.json";
|
||||
return "https://bmclapi2.bangbang93.com/mc/game/version_manifest.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionBaseURL() {
|
||||
return "http://bmclapi2.bangbang93.com/versions/";
|
||||
return "https://bmclapi2.bangbang93.com/versions/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAssetIndexBaseURL() {
|
||||
return "http://bmclapi2.bangbang93.com/indexes/";
|
||||
return "https://bmclapi2.bangbang93.com/indexes/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAssetBaseURL() {
|
||||
return "http://bmclapi2.bangbang93.com/assets/";
|
||||
return "https://bmclapi2.bangbang93.com/assets/";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,12 +78,12 @@ public class BMCLAPIDownloadProvider implements DownloadProvider {
|
||||
@Override
|
||||
public String injectURL(String baseURL) {
|
||||
return baseURL
|
||||
.replace("https://launchermeta.mojang.com", "http://bmclapi2.bangbang93.com")
|
||||
.replace("https://launcher.mojang.com", "http://bmclapi2.bangbang93.com")
|
||||
.replace("https://libraries.minecraft.net", "http://bmclapi2.bangbang93.com/libraries")
|
||||
.replaceFirst("https?://files\\.minecraftforge\\.net/maven", "http://bmclapi2.bangbang93.com/maven")
|
||||
.replace("http://dl.liteloader.com/versions/versions.json", "http://bmclapi2.bangbang93.com/maven/com/mumfrey/liteloader/versions.json")
|
||||
.replace("http://dl.liteloader.com/versions", "http://bmclapi2.bangbang93.com/maven");
|
||||
.replace("https://launchermeta.mojang.com", "https://bmclapi2.bangbang93.com")
|
||||
.replace("https://launcher.mojang.com", "https://bmclapi2.bangbang93.com")
|
||||
.replace("https://libraries.minecraft.net", "https://bmclapi2.bangbang93.com/libraries")
|
||||
.replaceFirst("https?://files\\.minecraftforge\\.net/maven", "https://bmclapi2.bangbang93.com/maven")
|
||||
.replace("http://dl.liteloader.com/versions/versions.json", "https://bmclapi2.bangbang93.com/maven/com/mumfrey/liteloader/versions.json")
|
||||
.replace("http://dl.liteloader.com/versions", "https://bmclapi2.bangbang93.com/maven");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,10 +17,12 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.download.game;
|
||||
|
||||
import org.jackhuang.hmcl.game.CompatibilityRule;
|
||||
import org.jackhuang.hmcl.game.Library;
|
||||
import org.jackhuang.hmcl.game.Version;
|
||||
import org.jackhuang.hmcl.task.TaskResult;
|
||||
import org.jackhuang.hmcl.util.Constants;
|
||||
import org.jackhuang.hmcl.util.Platform;
|
||||
import org.jackhuang.hmcl.util.SimpleMultimap;
|
||||
import org.jackhuang.hmcl.util.VersionNumber;
|
||||
|
||||
@@ -44,7 +46,6 @@ public class LibrariesUniqueTask extends TaskResult<Version> {
|
||||
public void execute() {
|
||||
List<Library> libraries = new ArrayList<>(version.getLibraries());
|
||||
|
||||
Map<String, VersionNumber> versionMap = new HashMap<>();
|
||||
SimpleMultimap<String, Library> multimap = new SimpleMultimap<String, Library>(HashMap::new, LinkedList::new);
|
||||
|
||||
for (Library library : libraries) {
|
||||
@@ -52,32 +53,36 @@ public class LibrariesUniqueTask extends TaskResult<Version> {
|
||||
VersionNumber number = VersionNumber.asVersion(library.getVersion());
|
||||
String serialized = Constants.GSON.toJson(library);
|
||||
|
||||
if (versionMap.containsKey(id)) {
|
||||
VersionNumber otherNumber = versionMap.get(id);
|
||||
if (number.compareTo(otherNumber) > 0) {
|
||||
multimap.removeKey(id);
|
||||
versionMap.put(id, number);
|
||||
multimap.put(id, library);
|
||||
} else if (number.compareTo(otherNumber) == 0) { // same library id.
|
||||
boolean flag = false;
|
||||
// prevent from duplicated libraries
|
||||
for (Library otherLibrary : multimap.get(id))
|
||||
if (library.equals(otherLibrary)) {
|
||||
String otherSerialized = Constants.GSON.toJson(otherLibrary);
|
||||
// A trick, the library that has more information is better, which can be
|
||||
// considered whose serialized JSON text will be longer.
|
||||
if (serialized.length() <= otherSerialized.length()) {
|
||||
flag = true;
|
||||
break;
|
||||
} else {
|
||||
multimap.removeValue(id, otherLibrary);
|
||||
if (multimap.containsKey(id)) {
|
||||
boolean hasEqualRule = false;
|
||||
for (Library otherLibrary : multimap.get(id)) {
|
||||
VersionNumber otherNumber = VersionNumber.asVersion(otherLibrary.getVersion());
|
||||
if (CompatibilityRule.equals(library.getRules(), otherLibrary.getRules())) { // rules equal, ignore older version.
|
||||
hasEqualRule = true;
|
||||
if (number.compareTo(otherNumber) > 0) { // if this library is newer
|
||||
multimap.removeValue(otherLibrary);
|
||||
multimap.put(id, library);
|
||||
break;
|
||||
} else if (number.compareTo(otherNumber) == 0) { // same library id.
|
||||
// prevent from duplicated libraries
|
||||
if (library.equals(otherLibrary)) {
|
||||
String otherSerialized = Constants.GSON.toJson(otherLibrary);
|
||||
// A trick, the library that has more information is better, which can be
|
||||
// considered whose serialized JSON text will be longer.
|
||||
if (serialized.length() > otherSerialized.length()) {
|
||||
multimap.removeValue(id, otherLibrary);
|
||||
multimap.put(id, library);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!flag)
|
||||
multimap.put(id, library);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasEqualRule) {
|
||||
multimap.put(id, library);
|
||||
}
|
||||
} else {
|
||||
versionMap.put(id, number);
|
||||
multimap.put(id, library);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,25 @@ public final class CompatibilityRule {
|
||||
return action == Action.ALLOW;
|
||||
}
|
||||
|
||||
public static boolean equals(Collection<CompatibilityRule> rules1, Collection<CompatibilityRule> rules2) {
|
||||
return Objects.hashCode(rules1) == Objects.hashCode(rules2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
CompatibilityRule that = (CompatibilityRule) o;
|
||||
return action == that.action &&
|
||||
Objects.equals(os, that.os) &&
|
||||
Objects.equals(features, that.features);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(action, os, features);
|
||||
}
|
||||
|
||||
public enum Action {
|
||||
ALLOW,
|
||||
DISALLOW
|
||||
|
||||
@@ -137,6 +137,10 @@ public class Library implements Comparable<Library> {
|
||||
return checksums;
|
||||
}
|
||||
|
||||
public List<CompatibilityRule> getRules() {
|
||||
return rules;
|
||||
}
|
||||
|
||||
public boolean is(String groupId, String artifactId) {
|
||||
return this.groupId.equals(groupId) && this.artifactId.equals(artifactId);
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ public class DefaultLauncher extends Launcher {
|
||||
if (isWindows) {
|
||||
writer.write("@echo off");
|
||||
writer.newLine();
|
||||
writer.write("set APPDATA=" + options.getGameDir().getParent());
|
||||
writer.write("set APPDATA=" + options.getGameDir().getAbsoluteFile().getParent());
|
||||
writer.newLine();
|
||||
writer.write("cd /D %APPDATA%");
|
||||
writer.newLine();
|
||||
|
||||
Reference in new issue
Block a user