Reland: create modpack with launcher packed in
This commit is contained in:
@@ -30,6 +30,7 @@ import org.jackhuang.hmcl.upgrade.UpdateHandler;
|
|||||||
import org.jackhuang.hmcl.util.CrashReporter;
|
import org.jackhuang.hmcl.util.CrashReporter;
|
||||||
import org.jackhuang.hmcl.util.Lang;
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
import org.jackhuang.hmcl.util.StringUtils;
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
@@ -158,6 +159,11 @@ public final class Launcher extends Application {
|
|||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
File jarFile = new File(Launcher.class.getProtectionDomain().getCodeSource().getLocation().getPath());
|
||||||
|
String ext = FileUtils.getExtension(jarFile);
|
||||||
|
if ("jar".equals(ext) || "exe".equals(ext))
|
||||||
|
result.add(jarFile);
|
||||||
}
|
}
|
||||||
if (result.isEmpty())
|
if (result.isEmpty())
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -25,19 +25,25 @@ import org.jackhuang.hmcl.mod.mcbbs.McbbsModpackExportTask;
|
|||||||
import org.jackhuang.hmcl.mod.multimc.MultiMCInstanceConfiguration;
|
import org.jackhuang.hmcl.mod.multimc.MultiMCInstanceConfiguration;
|
||||||
import org.jackhuang.hmcl.mod.multimc.MultiMCModpackExportTask;
|
import org.jackhuang.hmcl.mod.multimc.MultiMCModpackExportTask;
|
||||||
import org.jackhuang.hmcl.mod.server.ServerModpackExportTask;
|
import org.jackhuang.hmcl.mod.server.ServerModpackExportTask;
|
||||||
|
import org.jackhuang.hmcl.setting.Config;
|
||||||
|
import org.jackhuang.hmcl.setting.ConfigHolder;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.setting.VersionSetting;
|
import org.jackhuang.hmcl.setting.VersionSetting;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
||||||
import org.jackhuang.hmcl.util.Lang;
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
|
import org.jackhuang.hmcl.util.io.Zipper;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||||
|
|
||||||
public final class ExportWizardProvider implements WizardProvider {
|
public final class ExportWizardProvider implements WizardProvider {
|
||||||
private final Profile profile;
|
private final Profile profile;
|
||||||
private final String version;
|
private final String version;
|
||||||
@@ -55,31 +61,98 @@ public final class ExportWizardProvider implements WizardProvider {
|
|||||||
public Object finish(Map<String, Object> settings) {
|
public Object finish(Map<String, Object> settings) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<String> whitelist = (List<String>) settings.get(ModpackFileSelectionPage.MODPACK_FILE_SELECTION);
|
List<String> whitelist = (List<String>) settings.get(ModpackFileSelectionPage.MODPACK_FILE_SELECTION);
|
||||||
|
File modpackFile = (File) settings.get(ModpackInfoPage.MODPACK_FILE);
|
||||||
ModpackExportInfo exportInfo = (ModpackExportInfo) settings.get(ModpackInfoPage.MODPACK_INFO);
|
ModpackExportInfo exportInfo = (ModpackExportInfo) settings.get(ModpackInfoPage.MODPACK_INFO);
|
||||||
exportInfo.setWhitelist(whitelist);
|
exportInfo.setWhitelist(whitelist);
|
||||||
String modpackType = (String) settings.get(ModpackTypeSelectionPage.MODPACK_TYPE);
|
String modpackType = (String) settings.get(ModpackTypeSelectionPage.MODPACK_TYPE);
|
||||||
|
|
||||||
switch (modpackType) {
|
return exportWithLauncher(modpackType, exportInfo, modpackFile);
|
||||||
case ModpackTypeSelectionPage.MODPACK_TYPE_MCBBS:
|
|
||||||
return exportAsMcbbs(exportInfo);
|
|
||||||
case ModpackTypeSelectionPage.MODPACK_TYPE_MULTIMC:
|
|
||||||
return exportAsMultiMC(exportInfo);
|
|
||||||
case ModpackTypeSelectionPage.MODPACK_TYPE_SERVER:
|
|
||||||
return exportAsServer(exportInfo);
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException("Unrecognized modpack type " + modpackType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task<?> exportAsMcbbs(ModpackExportInfo exportInfo) {
|
private Task<?> exportWithLauncher(String modpackType, ModpackExportInfo exportInfo, File modpackFile) {
|
||||||
List<File> launcherJar = Launcher.getCurrentJarFiles();
|
List<File> launcherJar = Launcher.getCurrentJarFiles();
|
||||||
|
boolean packWithLauncher = exportInfo.isPackWithLauncher() && launcherJar != null;
|
||||||
|
return new Task<Object>() {
|
||||||
|
File tempModpack;
|
||||||
|
Task<?> exportTask;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doPreExecute() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preExecute() throws Exception {
|
||||||
|
File dest;
|
||||||
|
if (packWithLauncher) {
|
||||||
|
dest = tempModpack = Files.createTempFile("hmcl", ".zip").toFile();
|
||||||
|
} else {
|
||||||
|
dest = modpackFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (modpackType) {
|
||||||
|
case ModpackTypeSelectionPage.MODPACK_TYPE_MCBBS:
|
||||||
|
exportTask = exportAsMcbbs(exportInfo, dest);
|
||||||
|
break;
|
||||||
|
case ModpackTypeSelectionPage.MODPACK_TYPE_MULTIMC:
|
||||||
|
exportTask = exportAsMultiMC(exportInfo, dest);
|
||||||
|
break;
|
||||||
|
case ModpackTypeSelectionPage.MODPACK_TYPE_SERVER:
|
||||||
|
exportTask = exportAsServer(exportInfo, dest);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unrecognized modpack type " + modpackType);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Task<?>> getDependents() {
|
||||||
|
return Collections.singleton(exportTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws Exception {
|
||||||
|
if (!packWithLauncher) return;
|
||||||
|
try (Zipper zip = new Zipper(modpackFile.toPath())) {
|
||||||
|
Config exported = new Config();
|
||||||
|
|
||||||
|
exported.setBackgroundImageType(config().getBackgroundImageType());
|
||||||
|
exported.setBackgroundImage(config().getBackgroundImage());
|
||||||
|
exported.setTheme(config().getTheme());
|
||||||
|
exported.setDownloadType(config().getDownloadType());
|
||||||
|
exported.setPreferredLoginType(config().getPreferredLoginType());
|
||||||
|
exported.getAuthlibInjectorServers().setAll(config().getAuthlibInjectorServers());
|
||||||
|
|
||||||
|
zip.putTextFile(exported.toJson(), ConfigHolder.CONFIG_FILENAME);
|
||||||
|
zip.putFile(tempModpack, "modpack.zip");
|
||||||
|
|
||||||
|
File bg = new File("bg").getAbsoluteFile();
|
||||||
|
if (bg.isDirectory())
|
||||||
|
zip.putDirectory(bg.toPath(), "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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task<?> exportAsMcbbs(ModpackExportInfo exportInfo, File modpackFile) {
|
||||||
return new Task<Void>() {
|
return new Task<Void>() {
|
||||||
Task<?> dependency = null;
|
Task<?> dependency = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
dependency = new McbbsModpackExportTask(profile.getRepository(), version, exportInfo);
|
dependency = new McbbsModpackExportTask(profile.getRepository(), version, exportInfo, modpackFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -89,7 +162,7 @@ public final class ExportWizardProvider implements WizardProvider {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task<?> exportAsMultiMC(ModpackExportInfo exportInfo) {
|
private Task<?> exportAsMultiMC(ModpackExportInfo exportInfo, File modpackFile) {
|
||||||
return new Task<Void>() {
|
return new Task<Void>() {
|
||||||
Task<?> dependency;
|
Task<?> dependency;
|
||||||
|
|
||||||
@@ -122,7 +195,7 @@ public final class ExportWizardProvider implements WizardProvider {
|
|||||||
/* overrideConsole */ true,
|
/* overrideConsole */ true,
|
||||||
/* overrideCommands */ true,
|
/* overrideCommands */ true,
|
||||||
/* overrideWindow */ true
|
/* overrideWindow */ true
|
||||||
), exportInfo.getOutput().toFile());
|
), modpackFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -132,13 +205,13 @@ public final class ExportWizardProvider implements WizardProvider {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task<?> exportAsServer(ModpackExportInfo exportInfo) {
|
private Task<?> exportAsServer(ModpackExportInfo exportInfo, File modpackFile) {
|
||||||
return new Task<Void>() {
|
return new Task<Void>() {
|
||||||
Task<?> dependency;
|
Task<?> dependency;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
dependency = new ServerModpackExportTask(profile.getRepository(), version, exportInfo);
|
dependency = new ServerModpackExportTask(profile.getRepository(), version, exportInfo, modpackFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -121,7 +121,6 @@ public final class ModpackInfoPage extends Control implements WizardPage {
|
|||||||
exportInfo.setFileApi(fileApi.get());
|
exportInfo.setFileApi(fileApi.get());
|
||||||
exportInfo.setVersion(version.get());
|
exportInfo.setVersion(version.get());
|
||||||
exportInfo.setAuthor(author.get());
|
exportInfo.setAuthor(author.get());
|
||||||
exportInfo.setOutput(file.toPath());
|
|
||||||
exportInfo.setDescription(description.get());
|
exportInfo.setDescription(description.get());
|
||||||
exportInfo.setPackWithLauncher(packWithLauncher.get());
|
exportInfo.setPackWithLauncher(packWithLauncher.get());
|
||||||
exportInfo.setUrl(url.get());
|
exportInfo.setUrl(url.get());
|
||||||
@@ -139,6 +138,7 @@ public final class ModpackInfoPage extends Control implements WizardPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
controller.getSettings().put(MODPACK_INFO, exportInfo);
|
controller.getSettings().put(MODPACK_INFO, exportInfo);
|
||||||
|
controller.getSettings().put(MODPACK_FILE, file);
|
||||||
controller.onNext();
|
controller.onNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,6 +158,7 @@ public final class ModpackInfoPage extends Control implements WizardPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static final String MODPACK_INFO = "modpack.info";
|
public static final String MODPACK_INFO = "modpack.info";
|
||||||
|
public static final String MODPACK_FILE = "modpack.file";
|
||||||
public static final String MODPACK_INFO_OPTION = "modpack.info.option";
|
public static final String MODPACK_INFO_OPTION = "modpack.info.option";
|
||||||
|
|
||||||
public static class ModpackInfoPageSkin extends SkinBase<ModpackInfoPage> {
|
public static class ModpackInfoPageSkin extends SkinBase<ModpackInfoPage> {
|
||||||
@@ -288,8 +289,7 @@ public final class ModpackInfoPage extends Control implements WizardPage {
|
|||||||
list.getContent().add(pane);
|
list.getContent().add(pane);
|
||||||
|
|
||||||
JFXToggleButton button = new JFXToggleButton();
|
JFXToggleButton button = new JFXToggleButton();
|
||||||
button.setDisable(!skinnable.canIncludeLauncher);
|
button.selectedProperty().bindBidirectional(skinnable.forceUpdate);
|
||||||
button.selectedProperty().bindBidirectional(skinnable.packWithLauncher);
|
|
||||||
button.setSize(8);
|
button.setSize(8);
|
||||||
button.setMinHeight(16);
|
button.setMinHeight(16);
|
||||||
button.setMaxHeight(16);
|
button.setMaxHeight(16);
|
||||||
@@ -387,6 +387,20 @@ public final class ModpackInfoPage extends Control implements WizardPage {
|
|||||||
validatingFields.add(txtMcbbs);
|
validatingFields.add(txtMcbbs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
BorderPane pane = new BorderPane();
|
||||||
|
pane.setLeft(new Label(i18n("modpack.wizard.step.initialization.include_launcher")));
|
||||||
|
list.getContent().add(pane);
|
||||||
|
|
||||||
|
JFXToggleButton button = new JFXToggleButton();
|
||||||
|
button.setDisable(!skinnable.canIncludeLauncher);
|
||||||
|
button.selectedProperty().bindBidirectional(skinnable.packWithLauncher);
|
||||||
|
button.setSize(8);
|
||||||
|
button.setMinHeight(16);
|
||||||
|
button.setMaxHeight(16);
|
||||||
|
pane.setRight(button);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package org.jackhuang.hmcl.mod;
|
|||||||
import org.jackhuang.hmcl.mod.mcbbs.McbbsModpackManifest;
|
import org.jackhuang.hmcl.mod.mcbbs.McbbsModpackManifest;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -28,7 +27,6 @@ public class ModpackExportInfo {
|
|||||||
|
|
||||||
private String authlibInjectorServer;
|
private String authlibInjectorServer;
|
||||||
|
|
||||||
private Path output;
|
|
||||||
private List<McbbsModpackManifest.Origin> origins = new ArrayList<>();
|
private List<McbbsModpackManifest.Origin> origins = new ArrayList<>();
|
||||||
|
|
||||||
public ModpackExportInfo() {}
|
public ModpackExportInfo() {}
|
||||||
@@ -178,15 +176,6 @@ public class ModpackExportInfo {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Path getOutput() {
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModpackExportInfo setOutput(Path output) {
|
|
||||||
this.output = output;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<McbbsModpackManifest.Origin> getOrigins() {
|
public List<McbbsModpackManifest.Origin> getOrigins() {
|
||||||
return Collections.unmodifiableList(origins);
|
return Collections.unmodifiableList(origins);
|
||||||
}
|
}
|
||||||
@@ -198,8 +187,6 @@ public class ModpackExportInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ModpackExportInfo validate() throws NullPointerException {
|
public ModpackExportInfo validate() throws NullPointerException {
|
||||||
if (output == null)
|
|
||||||
throw new NullPointerException("ModpackExportInfo.output cannot be null");
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,14 +45,16 @@ public class McbbsModpackExportTask extends Task<Void> {
|
|||||||
private final DefaultGameRepository repository;
|
private final DefaultGameRepository repository;
|
||||||
private final String version;
|
private final String version;
|
||||||
private final ModpackExportInfo info;
|
private final ModpackExportInfo info;
|
||||||
|
private final File modpackFile;
|
||||||
|
|
||||||
public McbbsModpackExportTask(DefaultGameRepository repository, String version, ModpackExportInfo info) {
|
public McbbsModpackExportTask(DefaultGameRepository repository, String version, ModpackExportInfo info, File modpackFile) {
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.info = info.validate();
|
this.info = info.validate();
|
||||||
|
this.modpackFile = modpackFile;
|
||||||
|
|
||||||
onDone().register(event -> {
|
onDone().register(event -> {
|
||||||
if (event.isFailed()) this.info.getOutput().toFile().delete();
|
if (event.isFailed()) modpackFile.delete();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +64,7 @@ public class McbbsModpackExportTask extends Task<Void> {
|
|||||||
blackList.add(version + ".jar");
|
blackList.add(version + ".jar");
|
||||||
blackList.add(version + ".json");
|
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");
|
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 (Zipper zip = new Zipper(info.getOutput())) {
|
try (Zipper zip = new Zipper(modpackFile.toPath())) {
|
||||||
Path runDirectory = repository.getRunDirectory(version).toPath();
|
Path runDirectory = repository.getRunDirectory(version).toPath();
|
||||||
List<McbbsModpackManifest.File> files = new ArrayList<>();
|
List<McbbsModpackManifest.File> files = new ArrayList<>();
|
||||||
zip.putDirectory(runDirectory, "overrides", path -> {
|
zip.putDirectory(runDirectory, "overrides", path -> {
|
||||||
|
|||||||
@@ -45,14 +45,16 @@ public class ServerModpackExportTask extends Task<Void> {
|
|||||||
private final DefaultGameRepository repository;
|
private final DefaultGameRepository repository;
|
||||||
private final String versionId;
|
private final String versionId;
|
||||||
private final ModpackExportInfo exportInfo;
|
private final ModpackExportInfo exportInfo;
|
||||||
|
private final File modpackFile;
|
||||||
|
|
||||||
public ServerModpackExportTask(DefaultGameRepository repository, String version, ModpackExportInfo exportInfo) {
|
public ServerModpackExportTask(DefaultGameRepository repository, String version, ModpackExportInfo exportInfo, File modpackFile) {
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
this.versionId = version;
|
this.versionId = version;
|
||||||
this.exportInfo = exportInfo.validate();
|
this.exportInfo = exportInfo.validate();
|
||||||
|
this.modpackFile = modpackFile;
|
||||||
|
|
||||||
onDone().register(event -> {
|
onDone().register(event -> {
|
||||||
if (event.isFailed()) exportInfo.getOutput().toFile().delete();
|
if (event.isFailed()) modpackFile.delete();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +64,7 @@ public class ServerModpackExportTask extends Task<Void> {
|
|||||||
blackList.add(versionId + ".jar");
|
blackList.add(versionId + ".jar");
|
||||||
blackList.add(versionId + ".json");
|
blackList.add(versionId + ".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");
|
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 (Zipper zip = new Zipper(exportInfo.getOutput())) {
|
try (Zipper zip = new Zipper(modpackFile.toPath())) {
|
||||||
Path runDirectory = repository.getRunDirectory(versionId).toPath();
|
Path runDirectory = repository.getRunDirectory(versionId).toPath();
|
||||||
List<ModpackConfiguration.FileInformation> files = new ArrayList<>();
|
List<ModpackConfiguration.FileInformation> files = new ArrayList<>();
|
||||||
zip.putDirectory(runDirectory, "overrides", path -> {
|
zip.putDirectory(runDirectory, "overrides", path -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user