-
Notifications
You must be signed in to change notification settings - Fork 898
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
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 |
|---|---|---|
|
|
@@ -40,9 +40,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.FileSystem; | ||
| import java.nio.file.FileSystems; | ||
| import java.nio.file.Path; | ||
| 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 +58,11 @@ public final class LocalModpackPage extends ModpackPage { | |
| private Modpack manifest = null; | ||
| private Charset charset; | ||
|
|
||
| private final AtomicReference<FileSystem> wrapperFsRef = new AtomicReference<>(); | ||
| @Nullable | ||
| private volatile Path resolvedModpackFile; | ||
| private volatile boolean cleanedUp; | ||
|
|
||
| public LocalModpackPage(WizardController controller) { | ||
| super(controller); | ||
|
|
||
|
|
@@ -104,10 +114,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()) { | ||
| var wrapper = ModpackHelper.unwrapIfLauncherWrapper(selectedFile, encoding); | ||
| if (wrapper != null) { | ||
| actualFile = wrapper.innerPath(); | ||
| resolvedModpackFile = actualFile; | ||
| wrapperFsRef.set(wrapper.wrapperFs()); | ||
| } | ||
| } | ||
|
Comment on lines
+118
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
115
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; |
||
| FileSystem fs = wrapperFsRef.getAndSet(null); | ||
| if (fs != null) { | ||
| if (exception != null || cleanedUp) { | ||
| IOUtils.closeQuietly(fs); | ||
| } else { | ||
| Path innerPath = resolvedModpackFile; | ||
| if (innerPath != null) { | ||
| controller.getSettings().put(MODPACK_FILE, innerPath); | ||
| } | ||
| controller.getSettings().put(MODPACK_WRAPPER_FS, fs); | ||
| } | ||
| } | ||
|
|
||
| if (exception instanceof ManuallyCreatedModpackException) { | ||
| hideSpinner(); | ||
| nameProperty.set(FileUtils.getName(selectedFile)); | ||
|
|
@@ -146,7 +178,12 @@ public LocalModpackPage(WizardController controller) { | |
|
|
||
| @Override | ||
| public void cleanup(SettingsMap settings) { | ||
| cleanedUp = true; | ||
| settings.remove(MODPACK_FILE); | ||
| // 同时从 AtomicReference(后台任务可能尚未转移) | ||
| // 和 settings(可能已被 whenComplete 转移)中关闭 FS。 | ||
| IOUtils.closeQuietly(wrapperFsRef.getAndSet(null)); | ||
| IOUtils.closeQuietly(settings.remove(MODPACK_WRAPPER_FS)); | ||
| } | ||
|
Comment on lines
180
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() { | ||
|
|
@@ -179,6 +216,7 @@ protected void onDescribe() { | |
| } | ||
|
|
||
| public static final SettingsMap.Key<Path> MODPACK_FILE = new SettingsMap.Key<>("MODPACK_FILE"); | ||
| public static final SettingsMap.Key<FileSystem> MODPACK_WRAPPER_FS = new SettingsMap.Key<>("MODPACK_WRAPPER_FS"); | ||
|
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. |
||
| 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,与现有代码兼容