diff --git a/src/main/java/i18nupdatemod/I18nUpdateMod.java b/src/main/java/i18nupdatemod/I18nUpdateMod.java index 1afd352..fd0b0e3 100644 --- a/src/main/java/i18nupdatemod/I18nUpdateMod.java +++ b/src/main/java/i18nupdatemod/I18nUpdateMod.java @@ -18,10 +18,13 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.concurrent.*; +import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.Stream; public class I18nUpdateMod { + private static final int DOWNLOAD_WAIT_SECONDS = 10; public static final String MOD_ID = "i18nupdatemod"; public static String MOD_VERSION; @@ -55,37 +58,72 @@ public static void init(Path minecraftPath, String minecraftVersion, String load int minecraftMajorVersion = Integer.parseInt(minecraftVersion.split("\\.")[1]); - try { + CompletableFuture downloadTask = CompletableFuture.supplyAsync(() -> { //Get asset GameAssetDetail assets = I18nConfig.getAssetDetail(minecraftVersion, loader); + if (assets.downloads.isEmpty()) { + Log.info("No resource pack found for " + minecraftVersion + " with loader " + loader); + return new DownloadTaskResult(true, assets, "", null); + } //Update resource pack List languagePacks = new ArrayList<>(); + List> downloadTasks = new ArrayList<>(); boolean convertNotNeed = assets.downloads.size() == 1 && assets.downloads.get(0).targetVersion.equals(minecraftVersion); String applyFileName = assets.downloads.get(0).fileName; for (GameAssetDetail.AssetDownloadDetail it : assets.downloads) { FileUtil.setTemporaryDirPath(Paths.get(localStorage, "." + MOD_ID, it.targetVersion)); ResourcePack languagePack = new ResourcePack(it.fileName, convertNotNeed); - languagePack.checkUpdate(it.fileUrl, it.md5Url); + downloadTasks.add(CompletableFuture.runAsync(() -> { + try { + languagePack.checkUpdate(it.fileUrl, it.md5Url); + } catch (Exception e) { + throw new RuntimeException(e); + } + })); languagePacks.add(languagePack); } - //Convert resourcepack - if (!convertNotNeed) { - FileUtil.setTemporaryDirPath(Paths.get(localStorage, "." + MOD_ID, minecraftVersion)); - applyFileName = assets.covertFileName; - ResourcePackConverter converter = new ResourcePackConverter(languagePacks, applyFileName); - converter.convert(assets.covertPackFormat, getResourcePackDescription(assets.downloads)); + // Wait for all download tasks to complete + CompletableFuture.allOf(downloadTasks.toArray(new CompletableFuture[0])).join(); + return new DownloadTaskResult(convertNotNeed, assets, applyFileName, languagePacks); + }); + + // Convert and apply resource pack + Consumer convertAndApply = (result) -> { + if (result.assets.downloads.isEmpty()) { + return; } - //Apply resource pack - GameConfig config = new GameConfig(minecraftPath.resolve("options.txt")); - config.addResourcePack("Minecraft-Mod-Language-Modpack", - (minecraftMajorVersion <= 12 ? "" : "file/") + applyFileName); - config.writeToFile(); - } catch (Exception e) { - Log.warning(String.format("Failed to update resource pack: %s", e)); -// e.printStackTrace(); + try { + //Convert resourcepack + if (!result.convertNotNeed) { + FileUtil.setTemporaryDirPath(Paths.get(localStorage, "." + MOD_ID, minecraftVersion)); + result.applyFileName = result.assets.covertFileName; + ResourcePackConverter converter = new ResourcePackConverter(result.languagePacks, result.applyFileName); + converter.convert(result.assets.covertPackFormat, getResourcePackDescription(result.assets.downloads)); + } + + //Apply resource pack + GameConfig config = new GameConfig(minecraftPath.resolve("options.txt")); + config.addResourcePack("Minecraft-Mod-Language-Modpack", + (minecraftMajorVersion <= 12 ? "" : "file/") + result.applyFileName); + config.writeToFile(); + } catch (Exception e) { + Log.warning(String.format("Failed to convert and apply resource pack: %s", e)); + //e.printStackTrace(); + } + }; + + // Handle the download task result, if it completes within the timeout, apply the resource pack + try { + DownloadTaskResult r = downloadTask.get(DOWNLOAD_WAIT_SECONDS, TimeUnit.SECONDS); // Wait for the download task to complete + convertAndApply.accept(r); + } catch (TimeoutException ex) { + downloadTask.thenAccept(convertAndApply); + Log.info("Resource pack download take too long, will apply it when download finished."); + } catch (ExecutionException | InterruptedException ex) { + Log.warning(String.format("Failed to download resource pack: %s", ex.getCause())); } } @@ -121,4 +159,19 @@ public static String getLocalStoragePos(Path minecraftPath) { Objects::nonNull ).findFirst().orElse(xdgDataHome); } + + private static class DownloadTaskResult + { + public boolean convertNotNeed; + public GameAssetDetail assets; + public String applyFileName; + public List languagePacks; + + public DownloadTaskResult(boolean convertNotNeed, GameAssetDetail assets, String applyFileName, List languagePacks) { + this.convertNotNeed = convertNotNeed; + this.assets = assets; + this.applyFileName = applyFileName; + this.languagePacks = languagePacks; + } + } } \ No newline at end of file