-
Notifications
You must be signed in to change notification settings - Fork 911
fix(#6153): 导入包含启动器的整合包时提示"无法识别" #6225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
8fc013d
1590371
cddbec8
449cab2
31c27bb
e90914e
158036f
38937c6
9b0748f
ac753c9
3029455
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,6 +24,7 @@ | |
| import org.jackhuang.hmcl.game.HMCLGameRepository; | ||
| import org.jackhuang.hmcl.game.ManuallyCreatedModpackException; | ||
| import org.jackhuang.hmcl.game.ModpackHelper; | ||
| import org.jackhuang.hmcl.game.ModpackHelper.LauncherWrapper; | ||
| import org.jackhuang.hmcl.modpack.Modpack; | ||
| import org.jackhuang.hmcl.setting.Profile; | ||
| import org.jackhuang.hmcl.setting.Profiles; | ||
|
|
@@ -40,9 +41,14 @@ | |
| import org.jackhuang.hmcl.util.StringUtils; | ||
| import org.jackhuang.hmcl.util.io.CompressingUtils; | ||
| import org.jackhuang.hmcl.util.io.FileUtils; | ||
| import org.jackhuang.hmcl.util.io.IOUtils; | ||
| import org.jetbrains.annotations.Nullable; | ||
|
|
||
| import java.nio.charset.Charset; | ||
| import java.nio.file.FileSystems; | ||
| import java.nio.file.Path; | ||
| import java.util.Objects; | ||
| import java.util.concurrent.atomic.AtomicReference; | ||
|
|
||
| import static org.jackhuang.hmcl.util.logging.Logger.LOG; | ||
| import static org.jackhuang.hmcl.util.i18n.I18n.i18n; | ||
|
|
@@ -53,6 +59,10 @@ public final class LocalModpackPage extends ModpackPage { | |
| private Modpack manifest = null; | ||
| private Charset charset; | ||
|
|
||
| private final AtomicReference<LauncherWrapper> wrapperRef = new AtomicReference<>(); | ||
|
|
||
| private volatile boolean cleanedUp; | ||
|
|
||
| public LocalModpackPage(WizardController controller) { | ||
| super(controller); | ||
|
|
||
|
|
@@ -91,11 +101,12 @@ public LocalModpackPage(WizardController controller) { | |
| FileChooser chooser = new FileChooser(); | ||
| chooser.setTitle(i18n("modpack.choose")); | ||
| chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(i18n("modpack"), "*.zip")); | ||
| selectedFile = FileUtils.toPath(chooser.showOpenDialog(Controllers.getStage())); | ||
| if (selectedFile == null) { | ||
| Path chosenFile = FileUtils.toPath(chooser.showOpenDialog(Controllers.getStage())); | ||
| if (chosenFile == null) { | ||
| controller.onEnd(); | ||
| return; | ||
| } | ||
| selectedFile = chosenFile; | ||
|
|
||
| controller.getSettings().put(MODPACK_FILE, selectedFile); | ||
| } | ||
|
|
@@ -104,10 +115,32 @@ public LocalModpackPage(WizardController controller) { | |
| Task.supplyAsync(() -> CompressingUtils.findSuitableEncoding(selectedFile)) | ||
| .thenApplyAsync(encoding -> { | ||
| charset = encoding; | ||
| manifest = ModpackHelper.readModpackManifest(selectedFile, encoding); | ||
| Path actualFile = selectedFile; | ||
| if (selectedFile.getFileSystem() == FileSystems.getDefault()) { | ||
| LauncherWrapper wrapper = ModpackHelper.unwrapIfLauncherWrapper(selectedFile, encoding); | ||
| if (wrapper != null) { | ||
| actualFile = wrapper.innerPath(); | ||
| wrapperRef.set(wrapper); | ||
| } | ||
| } | ||
|
Comment on lines
+119
to
+125
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 配合 if (selectedFile.getFileSystem() == FileSystems.getDefault()) {
Path unwrapped = ModpackHelper.unwrapIfLauncherWrapper(selectedFile, encoding);
if (unwrapped != null) {
actualFile = unwrapped;
controller.getSettings().put(MODPACK_FILE, unwrapped);
Path oldTemp = controller.getSettings().put(MODPACK_TEMP_FILE, unwrapped);
if (oldTemp != null) {
try {
java.nio.file.Files.deleteIfExists(oldTemp);
} catch (IOException ignored) {
}
}
} else {
Path oldTemp = controller.getSettings().remove(MODPACK_TEMP_FILE);
if (oldTemp != null) {
try {
java.nio.file.Files.deleteIfExists(oldTemp);
} catch (IOException ignored) {
}
}
}
} |
||
| manifest = ModpackHelper.readModpackManifest(actualFile, encoding); | ||
| return manifest; | ||
| }) | ||
| .whenComplete(Schedulers.javafx(), (manifest, exception) -> { | ||
|
Comment on lines
116
to
129
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 在锠包包含启刨器的整合包包含启刨器的恐怕在快递切页或取消的情况下,帽步任务
解决方案: .thenApplyAsync(encoding -> {
charset = encoding;
Path actualFile = selectedFile;
if (selectedFile.getFileSystem() == FileSystems.getDefault()) {
var wrapper = ModpackHelper.unwrapIfLauncherWrapper(selectedFile, encoding);
if (wrapper != null) {
if (cleanedUp) {
try {
wrapper.getValue().close();
} catch (IOException ignored) {
}
return null;
}
actualFile = wrapper.getKey();
controller.getSettings().put(MODPACK_FILE, wrapper.getKey());
FileSystem oldFs = controller.getSettings().put(MODPACK_WRAPPER_FS, wrapper.getValue());
if (oldFs != null) {
try {
oldFs.close();
} catch (IOException ignored) {
// Ignore close errors for wrapper filesystem
}
}
} else {
FileSystem oldFs = controller.getSettings().remove(MODPACK_WRAPPER_FS);
if (oldFs != null) {
try {
oldFs.close();
} catch (IOException ignored) {
// Ignore close errors for wrapper filesystem
}
}
}
}
manifest = ModpackHelper.readModpackManifest(actualFile, encoding);
return manifest;
})
.whenComplete(Schedulers.javafx(), (manifest, exception) -> {
if (cleanedUp) return; |
||
| LauncherWrapper wrapper = wrapperRef.getAndSet(null); | ||
| if (wrapper != null) { | ||
| if (exception != null || cleanedUp) { | ||
| IOUtils.closeQuietly(wrapper); | ||
| } else { | ||
| controller.getSettings().put(MODPACK_FILE, wrapper.innerPath()); | ||
| controller.getSettings().put(MODPACK_WRAPPER, wrapper); | ||
| } | ||
| } | ||
|
|
||
| if (cleanedUp) { | ||
| return; | ||
| } | ||
|
|
||
| if (exception instanceof ManuallyCreatedModpackException) { | ||
| hideSpinner(); | ||
| nameProperty.set(FileUtils.getName(selectedFile)); | ||
|
|
@@ -129,27 +162,36 @@ public LocalModpackPage(WizardController controller) { | |
| Platform.runLater(controller::onEnd); | ||
| } else { | ||
| hideSpinner(); | ||
| controller.getSettings().put(MODPACK_MANIFEST, manifest); | ||
| nameProperty.set(manifest.getName()); | ||
| versionProperty.set(manifest.getVersion()); | ||
| authorProperty.set(manifest.getAuthor()); | ||
| Modpack parsedManifest = Objects.requireNonNull(manifest); | ||
| controller.getSettings().put(MODPACK_MANIFEST, parsedManifest); | ||
| nameProperty.set(parsedManifest.getName()); | ||
| versionProperty.set(parsedManifest.getVersion()); | ||
| authorProperty.set(parsedManifest.getAuthor()); | ||
|
|
||
| if (name == null) { | ||
| // trim: https://github.com/HMCL-dev/HMCL/issues/962 | ||
| txtModpackName.setText(manifest.getName().trim()); | ||
| txtModpackName.setText(parsedManifest.getName().trim()); | ||
| } | ||
|
|
||
| btnDescription.setVisible(StringUtils.isNotBlank(manifest.getDescription())); | ||
| btnDescription.setVisible(StringUtils.isNotBlank(parsedManifest.getDescription())); | ||
| } | ||
| }).start(); | ||
| } | ||
|
|
||
| @Override | ||
| public void cleanup(SettingsMap settings) { | ||
| cleanedUp = true; | ||
| settings.remove(MODPACK_FILE); | ||
| IOUtils.closeQuietly(wrapperRef.getAndSet(null)); | ||
| IOUtils.closeQuietly(settings.remove(MODPACK_WRAPPER)); | ||
| } | ||
|
Comment on lines
182
to
187
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 配合上述的 @Override
public void cleanup(SettingsMap settings) {
this.cleanedUp = true;
settings.remove(MODPACK_FILE);
FileSystem wrapperFs = settings.remove(MODPACK_WRAPPER_FS);
if (wrapperFs != null) {
try {
wrapperFs.close();
} catch (IOException ignored) {
// Ignore close errors for wrapper filesystem
}
}
} |
||
|
|
||
| protected void onInstall() { | ||
| Charset detectedCharset = charset; | ||
| if (detectedCharset == null) { | ||
| return; | ||
| } | ||
|
|
||
| String name = txtModpackName.getText(); | ||
|
|
||
| // Check for non-ASCII characters. | ||
|
|
@@ -160,15 +202,15 @@ protected void onInstall() { | |
| MessageDialogPane.MessageType.QUESTION) | ||
| .yesOrNo(() -> { | ||
| controller.getSettings().put(MODPACK_NAME, name); | ||
| controller.getSettings().put(MODPACK_CHARSET, charset); | ||
| controller.getSettings().put(MODPACK_CHARSET, detectedCharset); | ||
| controller.onFinish(); | ||
| }, () -> { | ||
| // The user selects Cancel and does nothing. | ||
| }) | ||
| .build()); | ||
| } else { | ||
| controller.getSettings().put(MODPACK_NAME, name); | ||
| controller.getSettings().put(MODPACK_CHARSET, charset); | ||
| controller.getSettings().put(MODPACK_CHARSET, detectedCharset); | ||
| controller.onFinish(); | ||
| } | ||
| } | ||
|
|
@@ -179,6 +221,9 @@ protected void onDescribe() { | |
| } | ||
|
|
||
| public static final SettingsMap.Key<Path> MODPACK_FILE = new SettingsMap.Key<>("MODPACK_FILE"); | ||
| public static final SettingsMap.Key<LauncherWrapper> MODPACK_WRAPPER = | ||
| new SettingsMap.Key<>("MODPACK_WRAPPER"); | ||
|
|
||
| public static final SettingsMap.Key<String> MODPACK_NAME = new SettingsMap.Key<>("MODPACK_NAME"); | ||
| public static final SettingsMap.Key<Modpack> MODPACK_MANIFEST = new SettingsMap.Key<>("MODPACK_MANIFEST"); | ||
| public static final SettingsMap.Key<Charset> MODPACK_CHARSET = new SettingsMap.Key<>("MODPACK_CHARSET"); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
为什么要用 ZipFileSystem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
可以在代码改动少且不解压临时文件的情况下实现这个功能
getPath 直接返回 Path,与现有代码兼容