mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-12 21:36:21 -04:00
MessageBox
This commit is contained in:
parent
9e21e02791
commit
8edfe7bc9c
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.mod.Modpack;
|
||||
import org.jackhuang.hmcl.task.TaskResult;
|
||||
import org.jackhuang.hmcl.util.Constants;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.ZipEngine;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Export the game to a mod pack file.
|
||||
*/
|
||||
public class HMCLModpackExportTask extends TaskResult<ZipEngine> {
|
||||
private final DefaultGameRepository repository;
|
||||
private final String version;
|
||||
private final List<String> whitelist;
|
||||
private final Modpack modpack;
|
||||
private final File output;
|
||||
private final String id;
|
||||
|
||||
public HMCLModpackExportTask(DefaultGameRepository repository, String version, List<String> whitelist, Modpack modpack, File output) {
|
||||
this(repository, version, whitelist, modpack, output, ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param output mod pack file.
|
||||
* @param version to locate version.json
|
||||
*/
|
||||
public HMCLModpackExportTask(DefaultGameRepository repository, String version, List<String> whitelist, Modpack modpack, File output, String id) {
|
||||
this.repository = repository;
|
||||
this.version = version;
|
||||
this.whitelist = whitelist;
|
||||
this.modpack = modpack;
|
||||
this.output = output;
|
||||
this.id = id;
|
||||
|
||||
onDone().register(event -> {
|
||||
if (event.isFailed()) output.delete();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
ArrayList<String> blackList = new ArrayList<>(HMCLModpackManager.MODPACK_BLACK_LIST);
|
||||
blackList.add(version + ".jar");
|
||||
blackList.add(version + ".json");
|
||||
Logging.LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
|
||||
try (ZipEngine zip = new ZipEngine(output)) {
|
||||
zip.putDirectory(repository.getRunDirectory(version), (String pathName, Boolean isDirectory) -> {
|
||||
for (String s : blackList)
|
||||
if (isDirectory) {
|
||||
if (pathName.startsWith(s + "/"))
|
||||
return null;
|
||||
} else if (pathName.equals(s))
|
||||
return null;
|
||||
for (String s : whitelist)
|
||||
if (pathName.equals(s + (isDirectory ? "/" : "")))
|
||||
return "minecraft/" + pathName;
|
||||
return null;
|
||||
});
|
||||
|
||||
Version mv = repository.getVersion(version).resolve(repository);
|
||||
String gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version));
|
||||
if (gameVersion == null)
|
||||
throw new IllegalStateException("Cannot parse the version of " + version);
|
||||
zip.putTextFile(Constants.GSON.toJson(mv.setJar(gameVersion)), "minecraft/pack.json"); // Making "jar" to gameVersion is to be compatible with old HMCL.
|
||||
zip.putTextFile(Constants.GSON.toJson(modpack.setGameVersion(gameVersion)), "modpack.json"); // Newer HMCL only reads 'gameVersion' field.
|
||||
}
|
||||
}
|
||||
|
||||
public static final String ID = "zip_engine";
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.game.VersionJsonSaveTask;
|
||||
import org.jackhuang.hmcl.mod.Modpack;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.CompressingUtils;
|
||||
import org.jackhuang.hmcl.util.Constants;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class HMCLModpackInstallTask extends Task {
|
||||
private final File zipFile;
|
||||
private final String version;
|
||||
private final HMCLGameRepository repository;
|
||||
private final DefaultDependencyManager dependency;
|
||||
private final List<Task> dependencies = new LinkedList<>();
|
||||
private final List<Task> dependents = new LinkedList<>();
|
||||
|
||||
public HMCLModpackInstallTask(Profile profile, File zipFile, Modpack modpack, String id) throws IOException {
|
||||
dependency = profile.getDependency();
|
||||
repository = profile.getRepository();
|
||||
this.zipFile = zipFile;
|
||||
this.version = id;
|
||||
|
||||
if (repository.hasVersion(id))
|
||||
throw new IllegalArgumentException("Version " + id + " already exists");
|
||||
|
||||
String json = CompressingUtils.readTextZipEntry(zipFile, "minecraft/pack.json");
|
||||
Version version = Constants.GSON.fromJson(json, Version.class).setJar(null);
|
||||
dependents.add(dependency.gameBuilder().name(id).gameVersion(modpack.getGameVersion()).buildAsync());
|
||||
dependencies.add(new VersionJsonSaveTask(repository, version));
|
||||
|
||||
onDone().register(event -> {
|
||||
if (event.isFailed()) repository.removeVersionFromDisk(id);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Task> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Task> getDependents() {
|
||||
return dependents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
CompressingUtils.unzip(zipFile, repository.getRunDirectory(version),
|
||||
"minecraft/", it -> !Objects.equals(it, "minecraft/pack.json"), false);
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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 com.google.gson.JsonParseException;
|
||||
import org.jackhuang.hmcl.mod.Modpack;
|
||||
import org.jackhuang.hmcl.task.TaskResult;
|
||||
import org.jackhuang.hmcl.util.*;
|
||||
import sun.rmi.runtime.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class HMCLModpackManager {
|
||||
|
||||
public static final List<String> MODPACK_BLACK_LIST = Arrays.asList("usernamecache.json", "asm", "logs", "backups", "versions", "assets", "usercache.json", "libraries", "crash-reports", "launcher_profiles.json", "NVIDIA", "AMD", "TCNodeTracker", "screenshots", "natives", "native", "$native", "pack.json", "launcher.jar", "minetweaker.log", "launcher.pack.lzma", "hmclmc.log");
|
||||
public static final List<String> MODPACK_SUGGESTED_BLACK_LIST = Arrays.asList("fonts", "saves", "servers.dat", "options.txt", "optionsof.txt", "journeymap", "optionsshaders.txt", "mods/VoxelMods");
|
||||
|
||||
public static ModAdviser MODPACK_PREDICATE = (String fileName, boolean isDirectory) -> {
|
||||
if (match(MODPACK_BLACK_LIST, fileName, isDirectory))
|
||||
return ModAdviser.ModSuggestion.HIDDEN;
|
||||
if (match(MODPACK_SUGGESTED_BLACK_LIST, fileName, isDirectory))
|
||||
return ModAdviser.ModSuggestion.NORMAL;
|
||||
else
|
||||
return ModAdviser.ModSuggestion.SUGGESTED;
|
||||
};
|
||||
|
||||
private static boolean match(List<String> l, String fileName, boolean isDirectory) {
|
||||
for (String s : l)
|
||||
if (isDirectory) {
|
||||
if (fileName.startsWith(s + "/"))
|
||||
return true;
|
||||
} else if (fileName.equals(s))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the manifest in a HMCL modpack.
|
||||
*
|
||||
* @param file a HMCL modpack file.
|
||||
* @throws IOException if the file is not a valid zip file.
|
||||
* @throws JsonParseException if the manifest.json is missing or malformed.
|
||||
* @return the manifest of HMCL modpack.
|
||||
*/
|
||||
public static Modpack readHMCLModpackManifest(File file) throws IOException, JsonParseException {
|
||||
String manifestJson = CompressingUtils.readTextZipEntry(file, "modpack.json");
|
||||
Modpack manifest = Constants.GSON.fromJson(manifestJson, Modpack.class);
|
||||
if (manifest == null)
|
||||
throw new JsonParseException("`modpack.json` not found. " + file + " is not a valid HMCL modpack.");
|
||||
String gameJson = CompressingUtils.readTextZipEntry(file, "minecraft/pack.json");
|
||||
Version game = Constants.GSON.fromJson(gameJson, Version.class);
|
||||
if (game == null)
|
||||
throw new JsonParseException("`minecraft/pack.json` not found. " + file + " iot a valid HMCL modpack.");
|
||||
if (game.getJar() == null)
|
||||
if (StringUtils.isBlank(manifest.getVersion()))
|
||||
throw new JsonParseException("Cannot recognize the game version of modpack " + file + ".");
|
||||
else
|
||||
return manifest.setManifest(HMCLModpackManifest.INSTANCE);
|
||||
else
|
||||
return manifest.setManifest(HMCLModpackManifest.INSTANCE).setGameVersion(game.getJar());
|
||||
}
|
||||
}
|
@ -15,10 +15,10 @@
|
||||
* 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.ui.wizard
|
||||
package org.jackhuang.hmcl.game;
|
||||
|
||||
import javafx.scene.Node
|
||||
public final class HMCLModpackManifest {
|
||||
public static final HMCLModpackManifest INSTANCE = new HMCLModpackManifest();
|
||||
|
||||
object Wizard {
|
||||
fun createWizard(namespace: String = "", provider: WizardProvider): Node = DefaultWizardDisplayer(namespace, provider)
|
||||
}
|
||||
private HMCLModpackManifest() {}
|
||||
}
|
@ -28,6 +28,10 @@ import java.util.List;
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class HMCLMultiCharacterSelector implements MultiCharacterSelector {
|
||||
public static final HMCLMultiCharacterSelector INSTANCE = new HMCLMultiCharacterSelector();
|
||||
|
||||
private HMCLMultiCharacterSelector() {}
|
||||
|
||||
@Override
|
||||
public GameProfile select(Account account, List<GameProfile> names) throws NoSelectedCharacterException {
|
||||
return names.stream().findFirst().orElseThrow(() -> new NoSelectedCharacterException(account));
|
||||
|
31
HMCL/src/main/java/org/jackhuang/hmcl/game/ModAdviser.java
Normal file
31
HMCL/src/main/java/org/jackhuang/hmcl/game/ModAdviser.java
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public interface ModAdviser {
|
||||
ModSuggestion advise(String fileName, boolean isDirectory);
|
||||
|
||||
enum ModSuggestion {
|
||||
SUGGESTED,
|
||||
NORMAL,
|
||||
HIDDEN
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.mod.CurseManifest;
|
||||
import org.jackhuang.hmcl.mod.Modpack;
|
||||
import org.jackhuang.hmcl.mod.MultiMCInstanceConfiguration;
|
||||
import org.jackhuang.hmcl.setting.EnumGameDirectory;
|
||||
import org.jackhuang.hmcl.setting.VersionSetting;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class ModpackHelper {
|
||||
private ModpackHelper() {}
|
||||
|
||||
public static Modpack readModpackManifest(File file) {
|
||||
try {
|
||||
return CurseManifest.readCurseForgeModpackManifest(file);
|
||||
} catch (Exception e) {
|
||||
// ignore it, not a valid CurseForge modpack.
|
||||
}
|
||||
|
||||
try {
|
||||
return HMCLModpackManager.readHMCLModpackManifest(file);
|
||||
} catch (Exception e) {
|
||||
// ignore it, not a valid HMCL modpack.
|
||||
}
|
||||
|
||||
try {
|
||||
return MultiMCInstanceConfiguration.readMultiMCModpackManifest(file);
|
||||
} catch (Exception e) {
|
||||
// ignore it, not a valid MultiMC modpack.
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Modpack file " + file + " is not supported.");
|
||||
}
|
||||
|
||||
public static void toVersionSetting(MultiMCInstanceConfiguration c, VersionSetting vs) {
|
||||
vs.setUsesGlobal(false);
|
||||
vs.setGameDirType(EnumGameDirectory.VERSION_FOLDER);
|
||||
|
||||
if (c.isOverrideJavaLocation()) {
|
||||
vs.setJavaDir(Lang.nonNull(c.getJavaPath(), ""));
|
||||
}
|
||||
|
||||
if (c.isOverrideMemory()) {
|
||||
vs.setPermSize(Optional.ofNullable(c.getPermGen()).map(i -> i.toString()).orElse(""));
|
||||
if (c.getMaxMemory() != null)
|
||||
vs.setMaxMemory(c.getMaxMemory());
|
||||
vs.setMinMemory(c.getMinMemory());
|
||||
}
|
||||
|
||||
if (c.isOverrideCommands()) {
|
||||
vs.setWrapper(Lang.nonNull(c.getWrapperCommand(), ""));
|
||||
vs.setPreLaunchCommand(Lang.nonNull(c.getPreLaunchCommand(), ""));
|
||||
}
|
||||
|
||||
if (c.isOverrideJavaArgs()) {
|
||||
vs.setJavaArgs(Lang.nonNull(c.getJvmArgs(), ""));
|
||||
}
|
||||
|
||||
if (c.isOverrideConsole()) {
|
||||
vs.setShowLogs(c.isShowConsole());
|
||||
}
|
||||
|
||||
if (c.isOverrideWindow()) {
|
||||
vs.setFullscreen(c.isFullscreen());
|
||||
if (c.getWidth() != null)
|
||||
vs.setWidth(c.getWidth());
|
||||
if (c.getHeight() != null)
|
||||
vs.setHeight(c.getHeight());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.mod.MultiMCInstanceConfiguration;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.setting.VersionSetting;
|
||||
import org.jackhuang.hmcl.task.Scheduler;
|
||||
import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
|
||||
public final class MultiMCInstallVersionSettingTask extends Task {
|
||||
private final Profile profile;
|
||||
private final MultiMCInstanceConfiguration manifest;
|
||||
private final String version;
|
||||
|
||||
public MultiMCInstallVersionSettingTask(Profile profile, MultiMCInstanceConfiguration manifest, String version) {
|
||||
this.profile = profile;
|
||||
this.manifest = manifest;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scheduler getScheduler() {
|
||||
return Schedulers.javafx();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
VersionSetting vs = profile.specializeVersionSetting(version);
|
||||
ModpackHelper.toVersionSetting(manifest, vs);
|
||||
}
|
||||
}
|
51
HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java
Normal file
51
HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.setting;
|
||||
|
||||
import org.jackhuang.hmcl.auth.Account;
|
||||
import org.jackhuang.hmcl.auth.AccountFactory;
|
||||
import org.jackhuang.hmcl.auth.OfflineAccount;
|
||||
import org.jackhuang.hmcl.auth.OfflineAccountFactory;
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount;
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccountFactory;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.Pair;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Accounts {
|
||||
private Accounts() {}
|
||||
|
||||
public static final String OFFLINE_ACCOUNT_KEY = "offline";
|
||||
public static final String YGGDRASIL_ACCOUNT_KEY = "yggdrasil";
|
||||
|
||||
public static final Map<String, AccountFactory<?>> ACCOUNT_FACTORY = Lang.mapOf(
|
||||
new Pair<>(OFFLINE_ACCOUNT_KEY, OfflineAccountFactory.INSTANCE),
|
||||
new Pair<>(YGGDRASIL_ACCOUNT_KEY, YggdrasilAccountFactory.INSTANCE)
|
||||
);
|
||||
|
||||
public static String getAccountType(Account account) {
|
||||
if (account instanceof OfflineAccount) return OFFLINE_ACCOUNT_KEY;
|
||||
else if (account instanceof YggdrasilAccount) return YGGDRASIL_ACCOUNT_KEY;
|
||||
else return YGGDRASIL_ACCOUNT_KEY;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.setting;
|
||||
|
||||
import org.jackhuang.hmcl.download.BMCLAPIDownloadProvider;
|
||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
import org.jackhuang.hmcl.download.MojangDownloadProvider;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public final class DownloadProviders {
|
||||
private DownloadProviders() {}
|
||||
|
||||
public static List<DownloadProvider> DOWNLOAD_PROVIDERS = Arrays.asList(MojangDownloadProvider.INSTANCE, BMCLAPIDownloadProvider.INSTANCE);
|
||||
|
||||
public static DownloadProvider getDownloadProvider(int index) {
|
||||
return Lang.get(DOWNLOAD_PROVIDERS, index).orElse(MojangDownloadProvider.INSTANCE);
|
||||
}
|
||||
}
|
28
HMCL/src/main/java/org/jackhuang/hmcl/setting/Fonts.java
Normal file
28
HMCL/src/main/java/org/jackhuang/hmcl/setting/Fonts.java
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.setting;
|
||||
|
||||
import javafx.scene.text.Font;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class Fonts {
|
||||
private Fonts() {}
|
||||
|
||||
public static final List<String> FONTS = Font.getFamilies();
|
||||
}
|
112
HMCL/src/main/java/org/jackhuang/hmcl/setting/Locales.java
Normal file
112
HMCL/src/main/java/org/jackhuang/hmcl/setting/Locales.java
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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.setting;
|
||||
|
||||
import org.jackhuang.hmcl.ui.construct.UTF8Control;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public final class Locales {
|
||||
|
||||
public static final SupportedLocale DEFAULT = new SupportedLocale(Locale.getDefault(), "lang.default");
|
||||
|
||||
/**
|
||||
* English
|
||||
*/
|
||||
public static final SupportedLocale EN = new SupportedLocale(Locale.ENGLISH);
|
||||
|
||||
/**
|
||||
* Traditional Chinese
|
||||
*/
|
||||
public static final SupportedLocale ZH = new SupportedLocale(Locale.TRADITIONAL_CHINESE);
|
||||
|
||||
/**
|
||||
* Simplified Chinese
|
||||
*/
|
||||
public static final SupportedLocale ZH_CN = new SupportedLocale(Locale.SIMPLIFIED_CHINESE);
|
||||
|
||||
/**
|
||||
* Vietnamese
|
||||
*/
|
||||
public static final SupportedLocale VI = new SupportedLocale(new Locale("vi"));
|
||||
|
||||
/**
|
||||
* Russian
|
||||
*/
|
||||
public static final SupportedLocale RU = new SupportedLocale(new Locale("ru"));
|
||||
|
||||
public static final List<SupportedLocale> LOCALES = Arrays.asList(DEFAULT, EN, ZH, ZH_CN, VI, RU);
|
||||
|
||||
public static SupportedLocale getLocale(int index) {
|
||||
return Lang.get(LOCALES, index).orElse(DEFAULT);
|
||||
}
|
||||
|
||||
public static SupportedLocale getLocaleByName(String name) {
|
||||
switch (name.toLowerCase()) {
|
||||
case "en": return EN;
|
||||
case "zh": return ZH;
|
||||
case "zh_cn": return ZH_CN;
|
||||
case "vi": return VI;
|
||||
case "ru": return RU;
|
||||
default: return DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getNameByLocale(SupportedLocale locale) {
|
||||
if (locale == EN) return "en";
|
||||
else if (locale == ZH) return "zh";
|
||||
else if (locale == ZH_CN) return "zh_CN";
|
||||
else if (locale == VI) return "vi";
|
||||
else if (locale == RU) return "ru";
|
||||
else if (locale == DEFAULT) return "def";
|
||||
else throw new IllegalArgumentException("Unknown locale: " + locale);
|
||||
}
|
||||
|
||||
public static class SupportedLocale {
|
||||
private final Locale locale;
|
||||
private final String name;
|
||||
private final ResourceBundle resourceBundle;
|
||||
|
||||
SupportedLocale(Locale locale) {
|
||||
this(locale, null);
|
||||
}
|
||||
|
||||
SupportedLocale(Locale locale, String name) {
|
||||
this.locale = locale;
|
||||
this.name = name;
|
||||
resourceBundle = ResourceBundle.getBundle("assets.lang.I18N", locale, UTF8Control.INSTANCE);
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public ResourceBundle getResourceBundle() {
|
||||
return resourceBundle;
|
||||
}
|
||||
|
||||
public String getName(ResourceBundle newResourceBundle) {
|
||||
if (name == null) return resourceBundle.getString("lang");
|
||||
else return newResourceBundle.getString(name);
|
||||
}
|
||||
}
|
||||
}
|
37
HMCL/src/main/java/org/jackhuang/hmcl/setting/Proxies.java
Normal file
37
HMCL/src/main/java/org/jackhuang/hmcl/setting/Proxies.java
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.setting;
|
||||
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
|
||||
import java.net.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Proxies {
|
||||
private Proxies() {}
|
||||
|
||||
public static final List<Proxy.Type> PROXIES = Arrays.asList(Proxy.Type.DIRECT, Proxy.Type.HTTP, Proxy.Type.SOCKS);
|
||||
|
||||
public static Proxy.Type getProxyType(int index) {
|
||||
return Lang.get(PROXIES, index).orElse(null);
|
||||
}
|
||||
}
|
@ -28,7 +28,11 @@ import java.util.Locale;
|
||||
import java.util.PropertyResourceBundle;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class UTF8Control extends ResourceBundle.Control {
|
||||
public final class UTF8Control extends ResourceBundle.Control {
|
||||
public static final UTF8Control INSTANCE = new UTF8Control();
|
||||
|
||||
private UTF8Control() {}
|
||||
|
||||
@Override
|
||||
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
|
||||
throws IllegalAccessException, InstantiationException, IOException {
|
||||
|
61
HMCL/src/main/java/org/jackhuang/hmcl/ui/wizard/Summary.java
Normal file
61
HMCL/src/main/java/org/jackhuang/hmcl/ui/wizard/Summary.java
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.ui.wizard;
|
||||
|
||||
import com.jfoenix.controls.JFXListView;
|
||||
import com.jfoenix.controls.JFXTextArea;
|
||||
import javafx.scene.Node;
|
||||
|
||||
/**
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Summary {
|
||||
private final Node component;
|
||||
private final Object result;
|
||||
|
||||
public Summary(String[] items, Object result) {
|
||||
JFXListView view = new JFXListView<String>();
|
||||
view.getItems().addAll(items);
|
||||
|
||||
this.component = view;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public Summary(String text, Object result) {
|
||||
JFXTextArea area = new JFXTextArea(text);
|
||||
area.setEditable(false);
|
||||
|
||||
this.component = area;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The component that will display the summary information
|
||||
*/
|
||||
public Node getComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* The object that represents the actual result of whatever that Wizard
|
||||
* that created this Summary object computes, or null.
|
||||
*/
|
||||
public Object getResult() {
|
||||
return result;
|
||||
}
|
||||
}
|
@ -15,27 +15,17 @@
|
||||
* 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.ui.wizard
|
||||
package org.jackhuang.hmcl.ui.wizard;
|
||||
|
||||
import com.jfoenix.controls.JFXListView
|
||||
import com.jfoenix.controls.JFXTextArea
|
||||
import javafx.scene.Node
|
||||
import javafx.scene.Node;
|
||||
|
||||
class Summary(
|
||||
/**
|
||||
* The component that will display the summary information
|
||||
*/
|
||||
val component: Node,
|
||||
/**
|
||||
* The object that represents the actual result of whatever that Wizard
|
||||
* that created this Summary object computes, or null.
|
||||
*/
|
||||
val result: Any?) {
|
||||
constructor(items: Array<String>, result: Any?)
|
||||
: this(JFXListView<String>().apply { this.items.addAll(*items) }, result) {
|
||||
public final class Wizard {
|
||||
|
||||
public static Node createWizard(WizardProvider provider) {
|
||||
return createWizard("", provider);
|
||||
}
|
||||
|
||||
constructor(text: String, result: Any?)
|
||||
: this(JFXTextArea(text).apply { isEditable = false }, result) {
|
||||
public static Node createWizard(String namespace, WizardProvider provider) {
|
||||
return new DefaultWizardDisplayer(namespace, provider);
|
||||
}
|
||||
}
|
||||
}
|
@ -42,6 +42,7 @@ import org.jackhuang.hmcl.Main;
|
||||
import org.jackhuang.hmcl.MainKt;
|
||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.Controllers;
|
||||
import org.jackhuang.hmcl.ui.construct.MessageBox;
|
||||
import org.jackhuang.hmcl.util.*;
|
||||
|
||||
@ -110,11 +111,13 @@ public class AppDataUpgrader extends IUpgrader {
|
||||
String hash = null;
|
||||
if (map.containsKey("jarsha1"))
|
||||
hash = map.get("jarsha1");
|
||||
if (TaskWindow.factory().append(new AppDataUpgraderJarTask(NetworkUtils.toURL(map.get("jar")), version.toString(), hash)).execute()) {
|
||||
Controllers.INSTANCE.dialog(MainKt.i18n("ui.message.downloading"));
|
||||
if (new AppDataUpgraderJarTask(NetworkUtils.toURL(map.get("jar")), version.toString(), hash).test()) {
|
||||
new ProcessBuilder(JavaVersion.fromCurrentEnvironment().getBinary().getAbsolutePath(), "-jar", AppDataUpgraderJarTask.getSelf(version.toString()).getAbsolutePath())
|
||||
.directory(new File("").getAbsoluteFile()).start();
|
||||
System.exit(0);
|
||||
}
|
||||
Controllers.INSTANCE.closeDialog();
|
||||
} catch (IOException ex) {
|
||||
Logging.LOG.log(Level.SEVERE, "Failed to create upgrader", ex);
|
||||
}
|
||||
@ -123,11 +126,13 @@ public class AppDataUpgrader extends IUpgrader {
|
||||
String hash = null;
|
||||
if (map.containsKey("packsha1"))
|
||||
hash = map.get("packsha1");
|
||||
if (TaskWindow.factory().append(new AppDataUpgraderPackGzTask(NetworkUtils.toURL(map.get("pack")), version.toString(), hash)).execute()) {
|
||||
Controllers.INSTANCE.dialog(MainKt.i18n("ui.message.downloading"));
|
||||
if (new AppDataUpgraderPackGzTask(NetworkUtils.toURL(map.get("pack")), version.toString(), hash).test()) {
|
||||
new ProcessBuilder(JavaVersion.fromCurrentEnvironment().getBinary().getAbsolutePath(), "-jar", AppDataUpgraderPackGzTask.getSelf(version.toString()).getAbsolutePath())
|
||||
.directory(new File("").getAbsoluteFile()).start();
|
||||
System.exit(0);
|
||||
}
|
||||
Controllers.INSTANCE.closeDialog();
|
||||
} catch (IOException ex) {
|
||||
Logging.LOG.log(Level.SEVERE, "Failed to create upgrader", ex);
|
||||
}
|
||||
|
@ -17,7 +17,9 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.upgrade;
|
||||
|
||||
import org.jackhuang.hmcl.MainKt;
|
||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||
import org.jackhuang.hmcl.ui.Controllers;
|
||||
import org.jackhuang.hmcl.util.Charsets;
|
||||
import org.jackhuang.hmcl.util.FileUtils;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
@ -51,7 +53,8 @@ public class NewFileUpgrader extends IUpgrader {
|
||||
URL url = requestDownloadLink();
|
||||
if (url == null) return;
|
||||
File newf = new File(url.getFile());
|
||||
if (TaskWindow.factory().append(new FileDownloadTask(url, newf)).execute()) {
|
||||
Controllers.INSTANCE.dialog(MainKt.i18n("ui.message.downloading"));
|
||||
if (new FileDownloadTask(url, newf).test()) {
|
||||
try {
|
||||
new ProcessBuilder(newf.getCanonicalPath(), "--removeOldLauncher", getRealPath())
|
||||
.directory(new File("").getAbsoluteFile())
|
||||
@ -61,6 +64,7 @@ public class NewFileUpgrader extends IUpgrader {
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
Controllers.INSTANCE.closeDialog();
|
||||
}
|
||||
|
||||
private static String getRealPath() {
|
||||
|
@ -1,167 +0,0 @@
|
||||
/*
|
||||
* 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 com.google.gson.JsonParseException
|
||||
import org.jackhuang.hmcl.download.game.VersionJsonSaveTask
|
||||
import org.jackhuang.hmcl.game.GameVersion.minecraftVersion
|
||||
import org.jackhuang.hmcl.mod.Modpack
|
||||
import org.jackhuang.hmcl.setting.Profile
|
||||
import org.jackhuang.hmcl.task.Task
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import org.jackhuang.hmcl.task.TaskResult
|
||||
import org.jackhuang.hmcl.util.*
|
||||
import org.jackhuang.hmcl.util.Constants.GSON
|
||||
import org.jackhuang.hmcl.util.Logging.LOG
|
||||
import java.util.ArrayList
|
||||
|
||||
/**
|
||||
* Read the manifest in a HMCL modpack.
|
||||
*
|
||||
* @param f a HMCL modpack file.
|
||||
* @throws IOException if the file is not a valid zip file.
|
||||
* @throws JsonParseException if the manifest.json is missing or malformed.
|
||||
* @return the manifest of HMCL modpack.
|
||||
*/
|
||||
@Throws(IOException::class, JsonParseException::class)
|
||||
fun readHMCLModpackManifest(f: File): Modpack {
|
||||
val manifestJson = CompressingUtils.readTextZipEntry(f, "modpack.json")
|
||||
val manifest = GSON.fromJson<Modpack>(manifestJson) ?: throw JsonParseException("`modpack.json` not found. $f is not a valid HMCL modpack.")
|
||||
val gameJson = CompressingUtils.readTextZipEntry(f, "minecraft/pack.json")
|
||||
val game = GSON.fromJson<Version>(gameJson) ?: throw JsonParseException("`minecraft/pack.json` not found. $f iot a valid HMCL modpack.")
|
||||
return if (game.jar == null)
|
||||
if (manifest.gameVersion.isNullOrBlank()) throw JsonParseException("Cannot recognize the game version of modpack $f.")
|
||||
else manifest.setManifest(HMCLModpackManifest)
|
||||
else manifest.setManifest(HMCLModpackManifest).setGameVersion(game.jar)
|
||||
}
|
||||
|
||||
object HMCLModpackManifest
|
||||
|
||||
class HMCLModpackInstallTask(profile: Profile, private val zipFile: File, modpack: Modpack, private val version: String): Task() {
|
||||
private val dependency = profile.dependency
|
||||
private val repository = profile.repository
|
||||
private val dependencies = mutableListOf<Task>()
|
||||
private val dependents = mutableListOf<Task>()
|
||||
|
||||
override fun getDependencies() = dependencies
|
||||
override fun getDependents() = dependents
|
||||
|
||||
init {
|
||||
check(!repository.hasVersion(version), { "Version $version already exists." })
|
||||
val json = CompressingUtils.readTextZipEntry(zipFile, "minecraft/pack.json")
|
||||
var version = GSON.fromJson<Version>(json)!!
|
||||
version = version.setJar(null)
|
||||
dependents += dependency.gameBuilder().name(this.version).gameVersion(modpack.gameVersion!!).buildAsync()
|
||||
dependencies += VersionJsonSaveTask(repository, version) // override the json created by buildAsync()
|
||||
|
||||
onDone() += { event -> if (event.isFailed) repository.removeVersionFromDisk(this.version) }
|
||||
}
|
||||
|
||||
private val run = repository.getRunDirectory(version)
|
||||
|
||||
override fun execute() {
|
||||
CompressingUtils.unzip(zipFile, run, "minecraft/", { it != "minecraft/pack.json" }, false)
|
||||
}
|
||||
}
|
||||
|
||||
val MODPACK_BLACK_LIST = listOf("usernamecache.json", "asm", "logs", "backups", "versions", "assets", "usercache.json", "libraries", "crash-reports", "launcher_profiles.json", "NVIDIA", "AMD", "TCNodeTracker", "screenshots", "natives", "native", "\$native", "pack.json", "launcher.jar", "minetweaker.log", "launcher.pack.lzma", "hmclmc.log")
|
||||
val MODPACK_NORMAL_LIST = listOf("fonts", "saves", "servers.dat", "options.txt", "optionsof.txt", "journeymap", "optionsshaders.txt", "mods/VoxelMods")
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
interface ModAdviser {
|
||||
|
||||
fun advise(fileName: String, isDirectory: Boolean): ModSuggestion
|
||||
|
||||
enum class ModSuggestion {
|
||||
SUGGESTED,
|
||||
NORMAL,
|
||||
HIDDEN
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun match(l: List<String>, fileName: String, isDirectory: Boolean): Boolean {
|
||||
for (s in l)
|
||||
if (isDirectory) {
|
||||
if (fileName.startsWith(s + "/"))
|
||||
return true
|
||||
} else if (fileName == s)
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
var MODPACK_PREDICATE = object : ModAdviser {
|
||||
override fun advise(fileName: String, isDirectory: Boolean): ModAdviser.ModSuggestion {
|
||||
return if (match(MODPACK_BLACK_LIST, fileName, isDirectory))
|
||||
ModAdviser.ModSuggestion.HIDDEN
|
||||
else if (match(MODPACK_NORMAL_LIST, fileName, isDirectory))
|
||||
ModAdviser.ModSuggestion.NORMAL
|
||||
else
|
||||
ModAdviser.ModSuggestion.SUGGESTED
|
||||
}
|
||||
}
|
||||
|
||||
class HMCLModpackExportTask @JvmOverloads constructor(
|
||||
private val repository: DefaultGameRepository,
|
||||
private val version: String,
|
||||
private val whitelist: List<String>,
|
||||
private val modpack: Modpack,
|
||||
private val output: File,
|
||||
private val id: String = ID): TaskResult<ZipEngine>() {
|
||||
|
||||
override fun getId() = id
|
||||
|
||||
init {
|
||||
onDone() += { event -> if (event.isFailed) output.delete() }
|
||||
}
|
||||
|
||||
override fun execute() {
|
||||
val blackList = ArrayList<String>(MODPACK_BLACK_LIST)
|
||||
blackList.add(version + ".jar")
|
||||
blackList.add(version + ".json")
|
||||
LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker")
|
||||
ZipEngine(output).use { zip ->
|
||||
zip.putDirectory(repository.getRunDirectory(version)) a@ { pathName: String, isDirectory: Boolean ->
|
||||
for (s in blackList) {
|
||||
if (isDirectory) {
|
||||
if (pathName.startsWith(s + "/"))
|
||||
return@a null
|
||||
} else if (pathName == s)
|
||||
return@a null
|
||||
}
|
||||
for (s in whitelist)
|
||||
if (s + (if (isDirectory) "/" else "") == pathName)
|
||||
return@a "minecraft/" + pathName
|
||||
null
|
||||
}
|
||||
|
||||
val mv = repository.getVersion(version).resolve(repository)
|
||||
val gameVersion = minecraftVersion(repository.getVersionJar(version)) ?: throw IllegalStateException("Cannot parse the version of $version")
|
||||
zip.putTextFile(GSON.toJson(mv.setJar(gameVersion)), "minecraft/pack.json") // Making "jar" to gameVersion is to be compatible with old HMCL.
|
||||
zip.putTextFile(GSON.toJson(modpack.setGameVersion(gameVersion)), "modpack.json") // Newer HMCL only reads 'gameVersion' field.
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = "zip_engine"
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* 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.mod.*
|
||||
import org.jackhuang.hmcl.setting.EnumGameDirectory
|
||||
import org.jackhuang.hmcl.setting.Profile
|
||||
import org.jackhuang.hmcl.setting.VersionSetting
|
||||
import org.jackhuang.hmcl.task.Schedulers
|
||||
import org.jackhuang.hmcl.task.Task
|
||||
import org.jackhuang.hmcl.util.toStringOrEmpty
|
||||
import java.io.File
|
||||
|
||||
fun readModpackManifest(f: File): Modpack {
|
||||
try {
|
||||
return CurseManifest.readCurseForgeModpackManifest(f);
|
||||
} catch (e: Exception) {
|
||||
// ignore it, not a valid CurseForge modpack.
|
||||
}
|
||||
|
||||
try {
|
||||
val manifest = readHMCLModpackManifest(f)
|
||||
return manifest
|
||||
} catch (e: Exception) {
|
||||
// ignore it, not a valid HMCL modpack.
|
||||
}
|
||||
|
||||
try {
|
||||
val manifest = MultiMCInstanceConfiguration.readMultiMCModpackManifest(f)
|
||||
return manifest
|
||||
} catch (e: Exception) {
|
||||
// ignore it, not a valid MMC modpack.
|
||||
}
|
||||
|
||||
throw IllegalArgumentException("Modpack file $f is not supported.")
|
||||
}
|
||||
|
||||
fun MultiMCInstanceConfiguration.toVersionSetting(vs: VersionSetting) {
|
||||
vs.isUsesGlobal = false
|
||||
vs.gameDirType = EnumGameDirectory.VERSION_FOLDER
|
||||
|
||||
if (isOverrideJavaLocation) {
|
||||
vs.javaDir = javaPath.toStringOrEmpty()
|
||||
}
|
||||
|
||||
if (isOverrideMemory) {
|
||||
vs.permSize = permGen.toStringOrEmpty()
|
||||
if (maxMemory != null)
|
||||
vs.maxMemory = maxMemory!!
|
||||
vs.minMemory = minMemory
|
||||
}
|
||||
|
||||
if (isOverrideCommands) {
|
||||
vs.wrapper = wrapperCommand.orEmpty()
|
||||
vs.preLaunchCommand = preLaunchCommand.orEmpty()
|
||||
}
|
||||
|
||||
if (isOverrideJavaArgs) {
|
||||
vs.javaArgs = jvmArgs.orEmpty()
|
||||
}
|
||||
|
||||
if (isOverrideConsole) {
|
||||
vs.isShowLogs = isShowConsole
|
||||
}
|
||||
|
||||
if (isOverrideWindow) {
|
||||
vs.isFullscreen = isFullscreen
|
||||
if (width != null)
|
||||
vs.width = width!!
|
||||
if (height != null)
|
||||
vs.height = height!!
|
||||
}
|
||||
}
|
||||
|
||||
class MMCInstallVersionSettingTask(private val profile: Profile, val manifest: MultiMCInstanceConfiguration, private val version: String): Task() {
|
||||
override fun getScheduler() = Schedulers.javafx()
|
||||
override fun execute() {
|
||||
val vs = profile.specializeVersionSetting(version)!!
|
||||
manifest.toVersionSetting(vs)
|
||||
}
|
||||
}
|
@ -149,7 +149,7 @@ object Settings {
|
||||
var locale: Locales.SupportedLocale = Locales.getLocaleByName(SETTINGS.localization)
|
||||
set(value) {
|
||||
field = value
|
||||
SETTINGS.localization = Locales.getNameByLocal(value)
|
||||
SETTINGS.localization = Locales.getNameByLocale(value)
|
||||
}
|
||||
|
||||
var proxy: Proxy = Proxy.NO_PROXY
|
||||
|
@ -1,110 +0,0 @@
|
||||
/*
|
||||
* 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.setting
|
||||
|
||||
import javafx.scene.text.Font
|
||||
import org.jackhuang.hmcl.auth.Account
|
||||
import org.jackhuang.hmcl.auth.AccountFactory
|
||||
import org.jackhuang.hmcl.auth.OfflineAccount
|
||||
import org.jackhuang.hmcl.auth.OfflineAccountFactory
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccountFactory
|
||||
import org.jackhuang.hmcl.download.BMCLAPIDownloadProvider
|
||||
import org.jackhuang.hmcl.download.MojangDownloadProvider
|
||||
import org.jackhuang.hmcl.ui.construct.UTF8Control
|
||||
import java.net.Proxy
|
||||
import java.util.*
|
||||
|
||||
object Proxies {
|
||||
val PROXIES = listOf(Proxy.Type.DIRECT, Proxy.Type.HTTP, Proxy.Type.SOCKS)
|
||||
|
||||
fun getProxyType(index: Int): Proxy.Type? = PROXIES.getOrNull(index)
|
||||
}
|
||||
|
||||
object DownloadProviders {
|
||||
val DOWNLOAD_PROVIDERS = listOf(MojangDownloadProvider.INSTANCE, BMCLAPIDownloadProvider.INSTANCE)
|
||||
|
||||
fun getDownloadProvider(index: Int) = DOWNLOAD_PROVIDERS.getOrElse(index, { MojangDownloadProvider.INSTANCE })
|
||||
}
|
||||
|
||||
object Accounts {
|
||||
val OFFLINE_ACCOUNT_KEY = "offline"
|
||||
val YGGDRASIL_ACCOUNT_KEY = "yggdrasil"
|
||||
|
||||
val ACCOUNT_FACTORY = mapOf<String, AccountFactory<*>>(
|
||||
OFFLINE_ACCOUNT_KEY to OfflineAccountFactory.INSTANCE,
|
||||
YGGDRASIL_ACCOUNT_KEY to YggdrasilAccountFactory.INSTANCE
|
||||
)
|
||||
|
||||
fun getAccountType(account: Account): String {
|
||||
return when (account) {
|
||||
is OfflineAccount -> OFFLINE_ACCOUNT_KEY
|
||||
is YggdrasilAccount -> YGGDRASIL_ACCOUNT_KEY
|
||||
else -> YGGDRASIL_ACCOUNT_KEY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object Locales {
|
||||
class SupportedLocale internal constructor(
|
||||
val locale: Locale,
|
||||
private val nameImpl: String? = null
|
||||
) {
|
||||
val resourceBundle: ResourceBundle = ResourceBundle.getBundle("assets.lang.I18N", locale, UTF8Control)
|
||||
|
||||
fun getName(nowResourceBundle: ResourceBundle): String {
|
||||
if (nameImpl == null)
|
||||
return resourceBundle.getString("lang")
|
||||
else
|
||||
return nowResourceBundle.getString(nameImpl)
|
||||
}
|
||||
}
|
||||
|
||||
val DEFAULT = SupportedLocale(Locale.getDefault(), "lang.default")
|
||||
val EN = SupportedLocale(Locale.ENGLISH)
|
||||
val ZH = SupportedLocale(Locale.TRADITIONAL_CHINESE)
|
||||
val ZH_CN = SupportedLocale(Locale.SIMPLIFIED_CHINESE)
|
||||
val VI = SupportedLocale(Locale("vi"))
|
||||
val RU = SupportedLocale(Locale("ru"))
|
||||
|
||||
val LOCALES = listOf(DEFAULT, EN, ZH, ZH_CN, VI, RU)
|
||||
|
||||
fun getLocale(index: Int) = LOCALES.getOrElse(index, { DEFAULT })
|
||||
fun getLocaleByName(name: String?) = when(name) {
|
||||
"en" -> EN
|
||||
"zh" -> ZH
|
||||
"zh_CN" -> ZH_CN
|
||||
"vi" -> VI
|
||||
"ru" -> RU
|
||||
else -> DEFAULT
|
||||
}
|
||||
|
||||
fun getNameByLocal(supportedLocale: SupportedLocale) = when(supportedLocale) {
|
||||
EN -> "en"
|
||||
ZH -> "zh"
|
||||
ZH_CN -> "zh_CN"
|
||||
VI -> "vi"
|
||||
RU -> "ru"
|
||||
DEFAULT -> "def"
|
||||
else -> throw IllegalArgumentException("Unknown argument: " + supportedLocale)
|
||||
}
|
||||
}
|
||||
|
||||
object Fonts {
|
||||
val FONTS = Font.getFamilies()
|
||||
}
|
@ -135,7 +135,7 @@ class AccountsPage() : StackPane(), DecoratorPage {
|
||||
else -> throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
account.logIn(HMCLMultiCharacterSelector, Settings.proxy)
|
||||
account.logIn(HMCLMultiCharacterSelector.INSTANCE, Settings.proxy)
|
||||
account
|
||||
} catch (e: Exception) {
|
||||
e
|
||||
|
@ -57,7 +57,7 @@ class YggdrasilAccountLoginPane(private val oldAccount: YggdrasilAccount, privat
|
||||
taskResult("login") {
|
||||
try {
|
||||
val account = YggdrasilAccountFactory.INSTANCE.fromUsername(username, password)
|
||||
account.logIn(HMCLMultiCharacterSelector, Settings.proxy)
|
||||
account.logIn(HMCLMultiCharacterSelector.INSTANCE, Settings.proxy)
|
||||
} catch (e: Exception) {
|
||||
e
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import javafx.scene.Parent
|
||||
import javafx.scene.SnapshotParameters
|
||||
import javafx.scene.image.ImageView
|
||||
import javafx.scene.image.WritableImage
|
||||
import javafx.scene.layout.Pane
|
||||
import javafx.scene.layout.StackPane
|
||||
import javafx.util.Duration
|
||||
import org.jackhuang.hmcl.ui.takeSnapshot
|
||||
@ -32,16 +33,17 @@ import org.jackhuang.hmcl.ui.takeSnapshot
|
||||
/**
|
||||
* @param view A stack pane that contains another control that is [Parent]
|
||||
*/
|
||||
class TransitionHandler(override val view: StackPane): AnimationHandler {
|
||||
class TransitionHandler(private val view: StackPane): AnimationHandler {
|
||||
private var animation: Timeline? = null
|
||||
|
||||
override val snapshot = ImageView().apply {
|
||||
override fun getSnapshot() = ImageView().apply {
|
||||
isPreserveRatio = true
|
||||
isSmooth = true
|
||||
}
|
||||
|
||||
override lateinit var duration: Duration
|
||||
private set
|
||||
override fun getView() = view
|
||||
private lateinit var duration: Duration
|
||||
override fun getDuration() = duration
|
||||
|
||||
fun setContent(newView: Node, transition: AnimationProducer, duration: Duration = Duration.millis(320.0)) {
|
||||
this.duration = duration
|
||||
|
@ -20,7 +20,7 @@ package org.jackhuang.hmcl.ui.download
|
||||
import javafx.scene.Node
|
||||
import org.jackhuang.hmcl.game.HMCLModpackInstallTask
|
||||
import org.jackhuang.hmcl.game.HMCLModpackManifest
|
||||
import org.jackhuang.hmcl.game.MMCInstallVersionSettingTask
|
||||
import org.jackhuang.hmcl.game.MultiMCInstallVersionSettingTask
|
||||
import org.jackhuang.hmcl.mod.*
|
||||
import org.jackhuang.hmcl.setting.EnumGameDirectory
|
||||
import org.jackhuang.hmcl.setting.Profile
|
||||
@ -80,7 +80,7 @@ class DownloadWizardProvider(): WizardProvider() {
|
||||
return when (modpack.manifest) {
|
||||
is CurseManifest -> CurseInstallTask(profile.dependency, selectedFile, modpack.manifest as CurseManifest, name)
|
||||
is HMCLModpackManifest -> HMCLModpackInstallTask(profile, selectedFile, modpack, name)
|
||||
is MultiMCInstanceConfiguration -> MultiMCModpackInstallTask(profile.dependency, selectedFile, modpack.manifest as MultiMCInstanceConfiguration, name).with(MMCInstallVersionSettingTask(profile, modpack.manifest as MultiMCInstanceConfiguration, name))
|
||||
is MultiMCInstanceConfiguration -> MultiMCModpackInstallTask(profile.dependency, selectedFile, modpack.manifest as MultiMCInstanceConfiguration, name).with(MultiMCInstallVersionSettingTask(profile, modpack.manifest as MultiMCInstanceConfiguration, name))
|
||||
else -> throw Error()
|
||||
}.with(finalizeTask)
|
||||
}
|
||||
|
@ -22,11 +22,10 @@ import com.jfoenix.controls.JFXTextField
|
||||
import javafx.application.Platform
|
||||
import javafx.fxml.FXML
|
||||
import javafx.scene.control.Label
|
||||
import javafx.scene.layout.BorderPane
|
||||
import javafx.scene.layout.Region
|
||||
import javafx.scene.layout.StackPane
|
||||
import javafx.stage.FileChooser
|
||||
import org.jackhuang.hmcl.game.readModpackManifest
|
||||
import org.jackhuang.hmcl.game.ModpackHelper
|
||||
import org.jackhuang.hmcl.i18n
|
||||
import org.jackhuang.hmcl.mod.Modpack
|
||||
import org.jackhuang.hmcl.setting.Profile
|
||||
@ -66,7 +65,7 @@ class ModpackPage(private val controller: WizardController): StackPane(), Wizard
|
||||
txtModpackName.textProperty().onInvalidated { btnInstall.isDisable = !txtModpackName.validate() }
|
||||
|
||||
try {
|
||||
manifest = readModpackManifest(selectedFile)
|
||||
manifest = ModpackHelper.readModpackManifest(selectedFile)
|
||||
controller.settings[MODPACK_CURSEFORGE_MANIFEST] = manifest!!
|
||||
lblName.text = manifest!!.name
|
||||
lblVersion.text = manifest!!.version
|
||||
|
@ -19,7 +19,7 @@ package org.jackhuang.hmcl.ui.export
|
||||
|
||||
import javafx.scene.Node
|
||||
import org.jackhuang.hmcl.game.HMCLModpackExportTask
|
||||
import org.jackhuang.hmcl.game.MODPACK_PREDICATE
|
||||
import org.jackhuang.hmcl.game.HMCLModpackManager.MODPACK_PREDICATE
|
||||
import org.jackhuang.hmcl.mod.Modpack
|
||||
import org.jackhuang.hmcl.setting.Profile
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController
|
||||
|
@ -171,6 +171,7 @@ ui.message.first_load=Please enter your name.
|
||||
ui.message.enter_password=Please enter your password.
|
||||
ui.message.launching=Launching...
|
||||
ui.message.making=Generating...
|
||||
ui.message.downloading=Downloading...
|
||||
ui.message.sure_remove=Sure to remove profile %s?
|
||||
ui.message.update_java=Please upgrade your Java.
|
||||
ui.message.open_jdk=We have found that you started this application using OpenJDK, which will cause so many troubles drawing the UI. We suggest you using Oracle JDK instead.
|
||||
|
@ -194,7 +194,7 @@ public abstract class Task {
|
||||
executor().start();
|
||||
}
|
||||
|
||||
public final boolean test() throws Exception {
|
||||
public final boolean test() {
|
||||
return executor().test();
|
||||
}
|
||||
|
||||
|
@ -182,6 +182,13 @@ public final class Lang {
|
||||
return (V) o;
|
||||
}
|
||||
|
||||
public static <V> Optional<V> get(List<V> list, int index) {
|
||||
if (index < 0 || index >= list.size())
|
||||
return Optional.empty();
|
||||
else
|
||||
return Optional.ofNullable(list.get(index));
|
||||
}
|
||||
|
||||
public static <V> Optional<V> get(Map<?, ?> map, Object key, Class<V> clazz) {
|
||||
return convert(map.get(key), clazz);
|
||||
}
|
||||
@ -248,4 +255,9 @@ public final class Lang {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T nonNull(T... t) {
|
||||
for (T a : t) if (a != null) return a;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user