mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-18 00:10:33 -04:00
Fix #360
This commit is contained in:
parent
c887d7e649
commit
1f30c299a5
@ -27,6 +27,7 @@ import org.jackhuang.hmcl.auth.ServerDisconnectException;
|
|||||||
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||||
import org.jackhuang.hmcl.download.MaintainTask;
|
import org.jackhuang.hmcl.download.MaintainTask;
|
||||||
import org.jackhuang.hmcl.launch.*;
|
import org.jackhuang.hmcl.launch.*;
|
||||||
|
import org.jackhuang.hmcl.mod.CurseCompletionException;
|
||||||
import org.jackhuang.hmcl.mod.CurseCompletionTask;
|
import org.jackhuang.hmcl.mod.CurseCompletionTask;
|
||||||
import org.jackhuang.hmcl.mod.ModpackConfiguration;
|
import org.jackhuang.hmcl.mod.ModpackConfiguration;
|
||||||
import org.jackhuang.hmcl.setting.LauncherVisibility;
|
import org.jackhuang.hmcl.setting.LauncherVisibility;
|
||||||
@ -177,11 +178,18 @@ public final class LauncherHelper {
|
|||||||
// because onStop will be invoked if tasks fail when the executor service shut down.
|
// because onStop will be invoked if tasks fail when the executor service shut down.
|
||||||
if (!Controllers.isStopped()) {
|
if (!Controllers.isStopped()) {
|
||||||
Controllers.closeDialog(launchingStepsPane);
|
Controllers.closeDialog(launchingStepsPane);
|
||||||
if (executor.getLastException() != null)
|
Exception ex = executor.getLastException();
|
||||||
Controllers.dialog(I18nException.getStackTrace(executor.getLastException()),
|
if (ex != null) {
|
||||||
|
String message;
|
||||||
|
if (ex instanceof CurseCompletionException)
|
||||||
|
message = Launcher.i18n("modpack.type.curse.error");
|
||||||
|
else
|
||||||
|
message = I18nException.getStackTrace(ex);
|
||||||
|
Controllers.dialog(message,
|
||||||
scriptFile == null ? Launcher.i18n("launch.failed") : Launcher.i18n("version.launch_script.failed"),
|
scriptFile == null ? Launcher.i18n("launch.failed") : Launcher.i18n("version.launch_script.failed"),
|
||||||
MessageBox.ERROR_MESSAGE);
|
MessageBox.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
launchingStepsPane.setExecutor(null);
|
launchingStepsPane.setExecutor(null);
|
||||||
|
@ -204,6 +204,7 @@ modpack.task.install.error=Failed to install the modpack. Maybe the files is inc
|
|||||||
modpack.task.install.will=Install the modpack:
|
modpack.task.install.will=Install the modpack:
|
||||||
modpack.type.curse=Curse
|
modpack.type.curse=Curse
|
||||||
modpack.type.curse.completion=Install relative files to Curse modpack
|
modpack.type.curse.completion=Install relative files to Curse modpack
|
||||||
|
modpack.type.curse.error=Unable to complete this Curse modpack. Please retry.
|
||||||
modpack.type.hmcl=HMCL
|
modpack.type.hmcl=HMCL
|
||||||
modpack.type.multimc=MultiMC
|
modpack.type.multimc=MultiMC
|
||||||
modpack.unsupported=Unsupported modpack, only HMCL, MultiMC, Curse modpacks are supported.
|
modpack.unsupported=Unsupported modpack, only HMCL, MultiMC, Curse modpacks are supported.
|
||||||
|
@ -204,6 +204,7 @@ modpack.task.install.error=安装失败,可能是整合包格式不正确或
|
|||||||
modpack.task.install.will=将会安装整合包:
|
modpack.task.install.will=将会安装整合包:
|
||||||
modpack.type.curse=Curse
|
modpack.type.curse=Curse
|
||||||
modpack.type.curse.completion=下载 Curse 整合包相关文件
|
modpack.type.curse.completion=下载 Curse 整合包相关文件
|
||||||
|
modpack.type.curse.error=未能完成 Curse 整合包的下载,请多次重试或设置代理
|
||||||
modpack.type.hmcl=HMCL
|
modpack.type.hmcl=HMCL
|
||||||
modpack.type.multimc=MultiMC
|
modpack.type.multimc=MultiMC
|
||||||
modpack.unsupported=该整合包不被支持。仅 HMCL、MultiMC、Curse 整合包受支持。
|
modpack.unsupported=该整合包不被支持。仅 HMCL、MultiMC、Curse 整合包受支持。
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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.mod;
|
||||||
|
|
||||||
|
public class CurseCompletionException extends Exception {
|
||||||
|
public CurseCompletionException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public CurseCompletionException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CurseCompletionException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CurseCompletionException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
@ -24,9 +24,11 @@ import org.jackhuang.hmcl.task.Task;
|
|||||||
import org.jackhuang.hmcl.util.*;
|
import org.jackhuang.hmcl.util.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -96,6 +98,7 @@ public final class CurseCompletionTask extends Task {
|
|||||||
File root = repository.getVersionRoot(version);
|
File root = repository.getVersionRoot(version);
|
||||||
File run = repository.getRunDirectory(version);
|
File run = repository.getRunDirectory(version);
|
||||||
|
|
||||||
|
AtomicBoolean flag = new AtomicBoolean(true);
|
||||||
AtomicInteger finished = new AtomicInteger(0);
|
AtomicInteger finished = new AtomicInteger(0);
|
||||||
|
|
||||||
// Because in China, Curse is too difficult to visit,
|
// Because in China, Curse is too difficult to visit,
|
||||||
@ -104,14 +107,32 @@ public final class CurseCompletionTask extends Task {
|
|||||||
manifest.getFiles().parallelStream()
|
manifest.getFiles().parallelStream()
|
||||||
.map(file -> {
|
.map(file -> {
|
||||||
updateProgress(finished.incrementAndGet(), manifest.getFiles().size());
|
updateProgress(finished.incrementAndGet(), manifest.getFiles().size());
|
||||||
return Lang.ignoringException(() -> file.setFileName(NetworkUtils.detectFileName(file.getUrl(), dependencyManager.getProxy())), file);
|
if (StringUtils.isBlank(file.getFileName())) {
|
||||||
|
try {
|
||||||
|
return file.withFileName(NetworkUtils.detectFileName(file.getUrl(), dependencyManager.getProxy()));
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
Logging.LOG.log(Level.WARNING, "Unable to fetch the file name of URL: " + file.getUrl(), ioe);
|
||||||
|
flag.set(false);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return file;
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
FileUtils.writeText(new File(root, "manifest.json"), Constants.GSON.toJson(newManifest));
|
FileUtils.writeText(new File(root, "manifest.json"), Constants.GSON.toJson(newManifest));
|
||||||
|
|
||||||
for (CurseManifestFile file : newManifest.getFiles())
|
for (CurseManifestFile file : newManifest.getFiles())
|
||||||
if (StringUtils.isNotBlank(file.getFileName()))
|
if (StringUtils.isNotBlank(file.getFileName())) {
|
||||||
dependencies.add(new FileDownloadTask(file.getUrl(), new File(run, "mods/" + file.getFileName()), dependencyManager.getProxy()));
|
File dest = new File(run, "mods/" + file.getFileName());
|
||||||
|
if (!dest.exists())
|
||||||
|
dependencies.add(new FileDownloadTask(file.getUrl(), dest, dependencyManager.getProxy()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let this task fail if the curse manifest has not been completed.
|
||||||
|
if (!flag.get())
|
||||||
|
dependencies.add(Task.of(() -> {
|
||||||
|
throw new CurseCompletionException();
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ public final class CurseManifestFile implements Validation {
|
|||||||
return NetworkUtils.toURL("https://minecraft.curseforge.com/projects/" + projectID + "/files/" + fileID + "/download");
|
return NetworkUtils.toURL("https://minecraft.curseforge.com/projects/" + projectID + "/files/" + fileID + "/download");
|
||||||
}
|
}
|
||||||
|
|
||||||
public CurseManifestFile setFileName(String fileName) {
|
public CurseManifestFile withFileName(String fileName) {
|
||||||
return new CurseManifestFile(projectID, fileID, fileName, required);
|
return new CurseManifestFile(projectID, fileID, fileName, required);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,10 +20,8 @@ package org.jackhuang.hmcl.util;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.*;
|
||||||
import java.net.MalformedURLException;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.net.Proxy;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
@ -138,9 +136,9 @@ public final class NetworkUtils {
|
|||||||
String disposition = conn.getHeaderField("Content-Disposition");
|
String disposition = conn.getHeaderField("Content-Disposition");
|
||||||
if (disposition == null || !disposition.contains("filename=")) {
|
if (disposition == null || !disposition.contains("filename=")) {
|
||||||
String u = conn.getURL().toString();
|
String u = conn.getURL().toString();
|
||||||
return substringAfterLast(u, '/');
|
return Lang.invoke(() -> URLDecoder.decode(substringAfterLast(u, '/'), StandardCharsets.UTF_8.name()));
|
||||||
} else
|
} else
|
||||||
return removeSurrounding(substringAfter(disposition, "filename="), "\"");
|
return Lang.invoke(() -> URLDecoder.decode(removeSurrounding(substringAfter(disposition, "filename="), "\""), StandardCharsets.UTF_8.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static URL toURL(String str) {
|
public static URL toURL(String str) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user