mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-01-30 14:39:56 +08:00
Try to fix ConcurrentModificationException
This commit is contained in:
parent
93837a28fa
commit
a9feb65fc8
@ -25,6 +25,7 @@ import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.Zipper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -75,7 +76,7 @@ public class HMCLModpackExportTask extends Task<Void> {
|
||||
|
||||
Version mv = repository.getResolvedVersion(version);
|
||||
String gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version))
|
||||
.orElseThrow(() -> new IllegalStateException("Cannot parse the version of " + version));
|
||||
.orElseThrow(() -> new IOException("Cannot parse the version of " + version));
|
||||
zip.putTextFile(JsonUtils.GSON.toJson(mv.setJar(gameVersion)), "minecraft/pack.json"); // Making "jar" to gameVersion is to be compatible with old HMCL.
|
||||
zip.putTextFile(JsonUtils.GSON.toJson(modpack.setGameVersion(gameVersion)), "modpack.json"); // Newer HMCL only reads 'gameVersion' field.
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ public final class ModpackHelper {
|
||||
return new MultiMCModpackInstallTask(profile.getDependency(), zipFile, modpack, ((MultiMCInstanceConfiguration) modpack.getManifest()), name)
|
||||
.whenComplete(Schedulers.defaultScheduler(), success, failure)
|
||||
.thenComposeAsync(new MultiMCInstallVersionSettingTask(profile, ((MultiMCInstanceConfiguration) modpack.getManifest()), name));
|
||||
else throw new IllegalStateException("Unrecognized modpack: " + modpack);
|
||||
else throw new IllegalArgumentException("Unrecognized modpack: " + modpack);
|
||||
}
|
||||
|
||||
public static Task<Void> getUpdateTask(Profile profile, File zipFile, Charset charset, String name, ModpackConfiguration<?> configuration) throws UnsupportedModpackException, MismatchedModpackTypeException {
|
||||
|
@ -18,9 +18,11 @@
|
||||
package org.jackhuang.hmcl.ui.download;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||
import org.jackhuang.hmcl.download.VersionMismatchException;
|
||||
import org.jackhuang.hmcl.download.fabric.FabricInstallTask;
|
||||
import org.jackhuang.hmcl.download.game.LibraryDownloadException;
|
||||
import org.jackhuang.hmcl.download.optifine.OptiFineInstallTask;
|
||||
import org.jackhuang.hmcl.game.Version;
|
||||
@ -114,9 +116,10 @@ public final class InstallerWizardProvider implements WizardProvider {
|
||||
} else {
|
||||
Controllers.dialog(i18n("install.failed.downloading.detail", ((DownloadException) exception).getUrl()) + "\n" + StringUtils.getStackTrace(exception.getCause()), i18n("install.failed.downloading"), MessageType.ERROR, next);
|
||||
}
|
||||
} else if (exception instanceof OptiFineInstallTask.UnsupportedOptiFineInstallationException) {
|
||||
} else if (exception instanceof OptiFineInstallTask.UnsupportedOptiFineInstallationException ||
|
||||
exception instanceof FabricInstallTask.UnsupportedFabricInstallationException) {
|
||||
Controllers.dialog(i18n("install.failed.optifine_conflict"), i18n("install.failed"), MessageType.ERROR, next);
|
||||
} else if (exception instanceof UnsupportedOperationException) {
|
||||
} else if (exception instanceof DefaultDependencyManager.UnsupportedLibraryInstallerException) {
|
||||
Controllers.dialog(i18n("install.failed.install_online"), i18n("install.failed"), MessageType.ERROR, next);
|
||||
} else if (exception instanceof VersionMismatchException) {
|
||||
VersionMismatchException e = ((VersionMismatchException) exception);
|
||||
|
@ -132,7 +132,7 @@ install.failed.downloading=Failed to install due to some files not downloaded su
|
||||
install.failed.downloading.detail=Failed to download file: %s
|
||||
install.failed.downloading.timeout=Download timed out: %s
|
||||
install.failed.install_online=Unable to recognize what you provided installer file is
|
||||
install.failed.optifine_conflict=OptiFine and Forge are both installed simultaneously on Minecraft 1.13
|
||||
install.failed.optifine_conflict=Fabric, OptiFine and Forge are both installed simultaneously on Minecraft 1.13
|
||||
install.failed.version_mismatch=The library requires game version %s, but actual version is %s.
|
||||
install.installer.choose=Choose a %s version
|
||||
install.installer.fabric=Fabric
|
||||
|
@ -94,7 +94,7 @@ public class DefaultDependencyManager extends AbstractDependencyManager {
|
||||
VersionList<?> versionList = getVersionList(libraryId);
|
||||
return versionList.loadAsync(gameVersion, getDownloadProvider())
|
||||
.thenComposeAsync(() -> installLibraryAsync(baseVersion, versionList.getVersion(gameVersion, libraryVersion)
|
||||
.orElseThrow(() -> new IllegalStateException("Remote library " + libraryId + " has no version " + libraryVersion))));
|
||||
.orElseThrow(() -> new IOException("Remote library " + libraryId + " has no version " + libraryVersion))));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -126,12 +126,15 @@ public class DefaultDependencyManager extends AbstractDependencyManager {
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("Library cannot be recognized");
|
||||
throw new UnsupportedLibraryInstallerException();
|
||||
})
|
||||
.thenApplyAsync(oldVersion::addPatch)
|
||||
.thenComposeAsync(repository::save);
|
||||
}
|
||||
|
||||
public static class UnsupportedLibraryInstallerException extends Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove installed library.
|
||||
* Will try to remove libraries and patches.
|
||||
|
@ -65,7 +65,7 @@ public final class FabricInstallTask extends Task<Version> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preExecute() {
|
||||
public void preExecute() throws Exception {
|
||||
if (!Objects.equals("net.minecraft.client.main.Main", version.resolve(dependencyManager.getGameRepository()).getMainClass()))
|
||||
throw new UnsupportedFabricInstallationException();
|
||||
}
|
||||
@ -128,6 +128,6 @@ public final class FabricInstallTask extends Task<Version> {
|
||||
return new Version("net.fabricmc", loaderVersion, 30000, arguments, mainClass, libraries);
|
||||
}
|
||||
|
||||
public static class UnsupportedFabricInstallationException extends UnsupportedOperationException {
|
||||
public static class UnsupportedFabricInstallationException extends Exception {
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||
import org.jackhuang.hmcl.util.platform.SystemUtils;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
@ -233,7 +234,7 @@ public class ForgeNewInstallTask extends Task<Version> {
|
||||
List<String> args = processor.getArgs().stream().map(arg -> {
|
||||
String parsed = parseLiteral(arg, data, ExceptionalFunction.identity());
|
||||
if (parsed == null)
|
||||
throw new IllegalStateException("Invalid forge installation configuration");
|
||||
throw new IOException("Invalid forge installation configuration");
|
||||
return parsed;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
@ -242,7 +243,7 @@ public class ForgeNewInstallTask extends Task<Version> {
|
||||
LOG.info("Executing external processor " + processor.getJar().toString() + ", command line: " + new CommandBuilder().addAll(command).toString());
|
||||
int exitCode = SystemUtils.callExternalProcess(command);
|
||||
if (exitCode != 0)
|
||||
throw new IllegalStateException("Game processor exited abnormally");
|
||||
throw new IOException("Game processor exited abnormally");
|
||||
|
||||
for (Map.Entry<String, String> entry : outputs.entrySet()) {
|
||||
Path artifact = Paths.get(entry.getKey());
|
||||
|
@ -24,6 +24,7 @@ import org.jackhuang.hmcl.task.GetTask;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@ -61,9 +62,9 @@ public final class VersionJsonDownloadTask extends Task<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
public void execute() throws IOException {
|
||||
RemoteVersion remoteVersion = gameVersionList.getVersion(gameVersion, gameVersion)
|
||||
.orElseThrow(() -> new IllegalStateException("Cannot find specific version " + gameVersion + " in remote repository"));
|
||||
.orElseThrow(() -> new IOException("Cannot find specific version " + gameVersion + " in remote repository"));
|
||||
String jsonURL = dependencyManager.getDownloadProvider().injectURL(remoteVersion.getUrl());
|
||||
dependencies.add(new GetTask(NetworkUtils.toURL(jsonURL)).storeTo(this::setResult));
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ public final class OptiFineInstallTask extends Task<Version> {
|
||||
gameRepository.getLibraryFile(version, optiFineLibrary).toString()
|
||||
);
|
||||
if (exitCode != 0)
|
||||
throw new IllegalStateException("OptiFine patcher failed");
|
||||
throw new IOException("OptiFine patcher failed");
|
||||
} else {
|
||||
FileUtils.copyFile(dest, gameRepository.getLibraryFile(version, optiFineLibrary).toPath());
|
||||
}
|
||||
@ -188,7 +188,7 @@ public final class OptiFineInstallTask extends Task<Version> {
|
||||
dependencies.add(dependencyManager.checkLibraryCompletionAsync(getResult()));
|
||||
}
|
||||
|
||||
public static class UnsupportedOptiFineInstallationException extends UnsupportedOperationException {
|
||||
public static class UnsupportedOptiFineInstallationException extends Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,6 +20,7 @@ package org.jackhuang.hmcl.event;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -27,12 +28,11 @@ import java.util.HashMap;
|
||||
*/
|
||||
public final class EventBus {
|
||||
|
||||
private final HashMap<Class<?>, EventManager<?>> events = new HashMap<>();
|
||||
private final ConcurrentHashMap<Class<?>, EventManager<?>> events = new ConcurrentHashMap<>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Event> EventManager<T> channel(Class<T> clazz) {
|
||||
if (!events.containsKey(clazz))
|
||||
events.put(clazz, new EventManager<>());
|
||||
events.putIfAbsent(clazz, new EventManager<>());
|
||||
return (EventManager<T>) events.get(clazz);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ import org.jackhuang.hmcl.util.SimpleMultimap;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@ -31,7 +32,7 @@ import java.util.function.Consumer;
|
||||
public final class EventManager<T extends Event> {
|
||||
|
||||
private final SimpleMultimap<EventPriority, Consumer<T>> handlers
|
||||
= new SimpleMultimap<>(() -> new EnumMap<>(EventPriority.class), HashSet::new);
|
||||
= new SimpleMultimap<>(() -> new EnumMap<>(EventPriority.class), CopyOnWriteArraySet::new);
|
||||
|
||||
public Consumer<T> registerWeak(Consumer<T> consumer) {
|
||||
register(new WeakListener(consumer));
|
||||
|
@ -54,6 +54,6 @@ public final class AssetObject implements Validation {
|
||||
@Override
|
||||
public void validate() throws JsonParseException {
|
||||
if (StringUtils.isBlank(hash) || hash.length() < 2)
|
||||
throw new IllegalStateException("AssetObject hash cannot be blank.");
|
||||
throw new JsonParseException("AssetObject hash cannot be blank.");
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ public class World {
|
||||
private void loadFromZipImpl(Path root) throws IOException {
|
||||
Path levelDat = root.resolve("level.dat");
|
||||
if (!Files.exists(levelDat))
|
||||
throw new IllegalArgumentException("Not a valid world zip file since level.dat cannot be found.");
|
||||
throw new IOException("Not a valid world zip file since level.dat cannot be found.");
|
||||
|
||||
getWorldName(levelDat);
|
||||
}
|
||||
@ -116,6 +116,9 @@ public class World {
|
||||
CompoundTag nbt = parseLevelDat(levelDat);
|
||||
|
||||
CompoundTag data = nbt.get("Data");
|
||||
if (data == null)
|
||||
throw new IOException("level.dat missing Data");
|
||||
|
||||
if (data.get("LevelName") instanceof StringTag)
|
||||
worldName = data.<StringTag>get("LevelName").getValue();
|
||||
else
|
||||
@ -209,7 +212,7 @@ public class World {
|
||||
return Files.list(savesDir).flatMap(world -> {
|
||||
try {
|
||||
return Stream.of(new World(world));
|
||||
} catch (IOException | IllegalArgumentException e) {
|
||||
} catch (IOException e) {
|
||||
Logging.LOG.log(Level.WARNING, "Failed to read world " + world, e);
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.Zipper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -80,7 +81,7 @@ public class MultiMCModpackExportTask extends Task<Void> {
|
||||
|
||||
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(repository.getResolvedPreservingPatchesVersion(versionId));
|
||||
String gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(versionId))
|
||||
.orElseThrow(() -> new IllegalStateException("Cannot parse the version of " + versionId));
|
||||
.orElseThrow(() -> new IOException("Cannot parse the version of " + versionId));
|
||||
List<MultiMCManifest.MultiMCManifestComponent> components = new ArrayList<>();
|
||||
components.add(new MultiMCManifest.MultiMCManifestComponent(true, false, "net.minecraft", gameVersion));
|
||||
analyzer.getVersion(FORGE).ifPresent(forgeVersion ->
|
||||
|
@ -292,7 +292,7 @@ public class FileDownloadTask extends Task<Void> {
|
||||
}
|
||||
|
||||
if (downloaded != contentLength)
|
||||
throw new IllegalStateException("Unexpected file size: " + downloaded + ", expected: " + contentLength);
|
||||
throw new IOException("Unexpected file size: " + downloaded + ", expected: " + contentLength);
|
||||
|
||||
// Integrity check
|
||||
if (integrityCheck != null) {
|
||||
@ -312,7 +312,7 @@ public class FileDownloadTask extends Task<Void> {
|
||||
}
|
||||
|
||||
return;
|
||||
} catch (IOException | IllegalStateException e) {
|
||||
} catch (IOException e) {
|
||||
if (temp != null)
|
||||
temp.toFile().delete();
|
||||
exception = e;
|
||||
|
@ -64,7 +64,7 @@ public final class TaskExecutor {
|
||||
Logging.LOG.log(Level.WARNING, "An exception occurred in task execution", exception);
|
||||
|
||||
Throwable resolvedException = resolveException(exception);
|
||||
if (resolvedException instanceof RuntimeException) {
|
||||
if (resolvedException instanceof RuntimeException && !(resolvedException instanceof CancellationException)) {
|
||||
// Track uncaught RuntimeException which are thrown mostly by our mistake
|
||||
if (uncaughtExceptionHandler != null)
|
||||
uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), resolvedException);
|
||||
|
Loading…
Reference in New Issue
Block a user