From 08f16f50cc1c425703323ec4c90071e8743fcafb Mon Sep 17 00:00:00 2001 From: BuildTools Date: Sun, 13 Aug 2023 11:31:47 +0300 Subject: [PATCH] Changes - Moved link obtainment into a separate interface - Adjusted ModDownloader to obtain links while downloading - Moved getFileName from Tools to FileUtils - Fixed wrong Forge version number --- .../main/java/net/kdt/pojavlaunch/Tools.java | 6 -- .../modpacks/api/CurseforgeApi.java | 27 +++++---- .../modpacks/api/ModDownloader.java | 58 +++++++++++++++---- .../modpacks/api/ModLoaderInfo.java | 9 +-- .../net/kdt/pojavlaunch/utils/FileUtils.java | 6 ++ .../src/main/res/values/strings.xml | 1 - 6 files changed, 72 insertions(+), 35 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java index b729b040f..792c3deb7 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -987,12 +987,6 @@ public final class Tools { return prefixedName.substring(Tools.LAUNCHERPROFILES_RTPREFIX.length()); } - public static String getFileName(String pathOrUrl) { - int lastSlashIndex = pathOrUrl.lastIndexOf('/'); - if(lastSlashIndex == -1) return null; - return pathOrUrl.substring(lastSlashIndex); - } - public static String getSelectedRuntime(MinecraftProfile minecraftProfile) { String runtime = LauncherPreferences.PREF_DEFAULT_RUNTIME; String profileRuntime = getRuntimeName(minecraftProfile.javaDir); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/CurseforgeApi.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/CurseforgeApi.java index 29e825666..c310189bd 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/CurseforgeApi.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/CurseforgeApi.java @@ -15,6 +15,7 @@ import net.kdt.pojavlaunch.modloaders.modpacks.models.ModDetail; import net.kdt.pojavlaunch.modloaders.modpacks.models.ModItem; import net.kdt.pojavlaunch.modloaders.modpacks.models.SearchFilters; import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper; +import net.kdt.pojavlaunch.utils.FileUtils; import net.kdt.pojavlaunch.utils.ZipUtils; import java.io.File; @@ -140,16 +141,18 @@ public class CurseforgeApi implements ModpackApi{ ModDownloader modDownloader = new ModDownloader(new File(instanceDestination,"mods"), true); int fileCount = curseManifest.files.length; for(int i = 0; i < fileCount; i++) { - CurseManifest.CurseFile curseFile = curseManifest.files[i]; - String downloadUrl = getDownloadUrl(curseFile.projectID, curseFile.fileID); - if(downloadUrl == null && curseFile.required) throw new IOException("Failed to obtain download URL for "+curseFile.projectID+" "+curseFile.fileID); - else if(downloadUrl == null) continue; - modDownloader.submitDownload(Tools.getFileName(downloadUrl), downloadUrl); - ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, (int) Math.max((float)i/fileCount*100,0), R.string.modpack_download_getting_links, i, fileCount); + final CurseManifest.CurseFile curseFile = curseManifest.files[i]; + modDownloader.submitDownload(()->{ + String url = getDownloadUrl(curseFile.projectID, curseFile.fileID); + if(url == null && curseFile.required) + throw new IOException("Failed to obtain download URL for "+curseFile.projectID+" "+curseFile.fileID); + else if(url == null) return null; + return new ModDownloader.FileInfo(url, FileUtils.getFileName(url)); + }); } - modDownloader.awaitFinish((c,m)->{ // insert joke about semen - ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, (int) Math.max((float)c/m*100,0), R.string.modpack_download_downloading_mods_fc, c, m); - }); + modDownloader.awaitFinish((c,m)-> + ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, (int) Math.max((float)c/m*100,0), R.string.modpack_download_downloading_mods_fc, c, m) + ); String overridesDir = "overrides"; if(curseManifest.overrides != null) overridesDir = curseManifest.overrides; ZipUtils.zipExtract(modpackZipFile, overridesDir, instanceDestination); @@ -170,7 +173,8 @@ public class CurseforgeApi implements ModpackApi{ int dashIndex = modLoaderId.indexOf('-'); String modLoaderName = modLoaderId.substring(0, dashIndex); String modLoaderVersion = modLoaderId.substring(dashIndex+1); - int modLoaderTypeInt = -1; + Log.i("CurseforgeApi", modLoaderId + " " + modLoaderName + " "+modLoaderVersion); + int modLoaderTypeInt; switch (modLoaderName) { case "forge": modLoaderTypeInt = ModLoaderInfo.MOD_LOADER_FORGE; @@ -178,9 +182,10 @@ public class CurseforgeApi implements ModpackApi{ case "fabric": modLoaderTypeInt = ModLoaderInfo.MOD_LOADER_FABRIC; break; + default: + return null; //TODO: Quilt is also Forge? How does that work? } - if(modLoaderTypeInt == -1) return null; return new ModLoaderInfo(modLoaderTypeInt, modLoaderVersion, minecraft.version); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/ModDownloader.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/ModDownloader.java index 505df2944..09ddd7c6e 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/ModDownloader.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/ModDownloader.java @@ -29,6 +29,7 @@ public class ModDownloader { } public ModDownloader(File destinationDirectory, boolean useFileCount) { + this.mDownloadPool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy()); this.mDestinationDirectory = destinationDirectory; this.mUseFileCount = useFileCount; } @@ -39,20 +40,20 @@ public class ModDownloader { mDownloadPool.execute(new DownloadTask(url, new File(mDestinationDirectory, relativePath))); } - public void submitDownload(String relativePath, String... url) { + public void submitDownload(FileInfoProvider infoProvider) { if(!mUseFileCount) throw new RuntimeException("This method can only be used in a file-counting ModDownloader"); mTotalSize += 1; - mDownloadPool.execute(new DownloadTask(url, new File(mDestinationDirectory, relativePath))); + mDownloadPool.execute(new FileInfoQueryTask(infoProvider)); } - public void awaitFinish(Tools.DownloaderFeedback feedback) throws IOException{ + public void awaitFinish(Tools.DownloaderFeedback feedback) throws IOException { try { mDownloadPool.shutdown(); while(!mDownloadPool.awaitTermination(20, TimeUnit.MILLISECONDS) && !mTerminator.get()) { feedback.updateProgress((int) mDownloadSize.get(), (int) mTotalSize); } - if(mTerminator.get()) { + mDownloadPool.shutdownNow(); synchronized (mExceptionSyncPoint) { if(mFirstIOException == null) mExceptionSyncPoint.wait(); throw mFirstIOException; @@ -71,6 +72,34 @@ public class ModDownloader { return buffer; } + private void downloadFailed(IOException exception) { + mTerminator.set(true); + synchronized (mExceptionSyncPoint) { + if(mFirstIOException == null) { + mFirstIOException = exception; + mExceptionSyncPoint.notify(); + } + } + } + + class FileInfoQueryTask implements Runnable { + private final FileInfoProvider mFileInfoProvider; + public FileInfoQueryTask(FileInfoProvider fileInfoProvider) { + this.mFileInfoProvider = fileInfoProvider; + } + @Override + public void run() { + try { + FileInfo fileInfo = mFileInfoProvider.getFileInfo(); + if(fileInfo == null) return; + new DownloadTask(new String[]{fileInfo.url}, + new File(mDestinationDirectory, fileInfo.relativePath)).run(); + }catch (IOException e) { + downloadFailed(e); + } + } + } + class DownloadTask implements Runnable, Tools.DownloaderFeedback { private final String[] mDownloadUrls; private final File mDestination; @@ -94,12 +123,7 @@ public class ModDownloader { } } if(exception != null) { - synchronized (mExceptionSyncPoint) { - if(mFirstIOException == null) { - mFirstIOException = exception; - mExceptionSyncPoint.notify(); - } - } + downloadFailed(exception); } } @@ -131,4 +155,18 @@ public class ModDownloader { last = curr; } } + + public static class FileInfo { + public final String url; + public final String relativePath; + + public FileInfo(String url, String relativePath) { + this.url = url; + this.relativePath = relativePath; + } + } + + public interface FileInfoProvider { + FileInfo getFileInfo() throws IOException; + } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/ModLoaderInfo.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/ModLoaderInfo.java index 9464573b6..556ab3acc 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/ModLoaderInfo.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/ModLoaderInfo.java @@ -1,10 +1,5 @@ package net.kdt.pojavlaunch.modloaders.modpacks.api; -import android.content.Context; -import android.content.Intent; - -import net.kdt.pojavlaunch.JavaGUILauncherActivity; - public class ModLoaderInfo { public static final int MOD_LOADER_FORGE = 0; public static final int MOD_LOADER_FABRIC = 1; @@ -22,11 +17,11 @@ public class ModLoaderInfo { public String getVersionId() { switch (modLoaderType) { case MOD_LOADER_FORGE: - return minecraftVersion+"-forge-"+modLoaderType; + return minecraftVersion+"-forge-"+modLoaderVersion; case MOD_LOADER_FABRIC: return "fabric-loader-"+modLoaderVersion+"-"+minecraftVersion; case MOD_LOADER_QUILT: - throw new RuntimeException("Quilt is gay af"); + throw new RuntimeException("Quilt is not supported"); default: return null; } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/FileUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/FileUtils.java index 81e5b875f..93635d276 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/FileUtils.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/FileUtils.java @@ -41,6 +41,12 @@ public class FileUtils { zis.close(); } + public static String getFileName(String pathOrUrl) { + int lastSlashIndex = pathOrUrl.lastIndexOf('/'); + if(lastSlashIndex == -1) return null; + return pathOrUrl.substring(lastSlashIndex); + } + public static File newFile(File destinationDir, ZipEntry zipEntry) throws IOException { File destFile = new File(destinationDir, zipEntry.getName()); diff --git a/app_pojavlauncher/src/main/res/values/strings.xml b/app_pojavlauncher/src/main/res/values/strings.xml index 03188d94f..5958bd3eb 100644 --- a/app_pojavlauncher/src/main/res/values/strings.xml +++ b/app_pojavlauncher/src/main/res/values/strings.xml @@ -416,7 +416,6 @@ Downloading modpack metadata (%.2f MB / %.2f MB) Downloading mods (%.2f MB / %.2f MB) - Downloading mod links (%d/%d) Downloading mods (File %d out of %d) Applying overrides (%d/%d)