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)