11package net .kdt .pojavlaunch ;
22
33import static net .kdt .pojavlaunch .Architecture .archAsString ;
4+ import static net .kdt .pojavlaunch .Architecture .getDeviceArchitecture ;
5+ import static net .kdt .pojavlaunch .Tools .NATIVE_LIB_DIR ;
6+ import static net .kdt .pojavlaunch .Tools .isOnline ;
47
58import android .app .Activity ;
9+ import android .content .Context ;
610import android .content .res .AssetManager ;
711import android .util .Log ;
812
13+ import com .kdt .mcgui .ProgressLayout ;
14+
915import net .kdt .pojavlaunch .multirt .MultiRTUtils ;
1016import net .kdt .pojavlaunch .multirt .Runtime ;
17+ import net .kdt .pojavlaunch .progresskeeper .DownloaderProgressWrapper ;
18+ import net .kdt .pojavlaunch .utils .DownloadUtils ;
1119import net .kdt .pojavlaunch .utils .MathUtils ;
1220import net .kdt .pojavlaunch .value .launcherprofiles .LauncherProfiles ;
1321import net .kdt .pojavlaunch .value .launcherprofiles .MinecraftProfile ;
1422
23+ import java .io .File ;
24+ import java .io .FileInputStream ;
1525import java .io .IOException ;
1626import java .util .Arrays ;
1727import java .util .List ;
@@ -56,7 +66,7 @@ private static InternalRuntime getInternalRuntime(Runtime runtime) {
5666 }
5767
5868 private static MathUtils .RankedValue <Runtime > getNearestInstalledRuntime (int targetVersion ) {
59- List <Runtime > runtimes = MultiRTUtils .getRuntimes ();
69+ List <Runtime > runtimes = MultiRTUtils .getInstalledRuntimes ();
6070 return MathUtils .findNearestPositive (targetVersion , runtimes , (runtime )->runtime .javaVersion );
6171 }
6272
@@ -84,7 +94,7 @@ public static boolean installNewJreIfNeeded(Activity activity, JMinecraftVersion
8494 // Check whether the selection is an internal runtime
8595 InternalRuntime internalRuntime = getInternalRuntime (runtime );
8696 // If it is, check if updates are available from the APK file
87- if (internalRuntime != null ) {
97+ if (internalRuntime != null ) {
8898 // Not calling showRuntimeFail on failure here because we did, technically, find the compatible runtime
8999 return checkInternalRuntime (assetManager , internalRuntime );
90100 }
@@ -100,6 +110,18 @@ public static boolean installNewJreIfNeeded(Activity activity, JMinecraftVersion
100110 nearestInternalRuntime , nearestInstalledRuntime , (value )->value .rank
101111 );
102112
113+ // Check if the selected runtime actually exists in the APK, else download it
114+ // If it isn't InternalRuntime then it wasn't in the apk in the first place!
115+ if (selectedRankedRuntime .value instanceof InternalRuntime )
116+ if (!checkInternalRuntime (assetManager , (InternalRuntime ) selectedRankedRuntime .value )) {
117+ if (nearestInstalledRuntime == null ) // If this was non-null then it would be a valid runtime and we can leave it be
118+ tryDownloadRuntime (activity , gameRequiredVersion );
119+ // This means the internal runtime didn't extract so let's use installed instead
120+ // This also refreshes it so after the runtime download, it can find the new runtime
121+ selectedRankedRuntime = getNearestInstalledRuntime (gameRequiredVersion );
122+ }
123+
124+
103125 // No possible selections
104126 if (selectedRankedRuntime == null ) {
105127 showRuntimeFail (activity , versionInfo );
@@ -141,6 +163,47 @@ private static void showRuntimeFail(Activity activity, JMinecraftVersionList.Ver
141163 activity .getString (R .string .multirt_nocompatiblert , verInfo .javaVersion .majorVersion ));
142164 }
143165
166+ public static boolean isJavaVersionAvailableForDownload (int version ) {
167+ for (ExternalRuntime javaVersion : ExternalRuntime .values ()) {
168+ if (javaVersion .majorVersion == version ) {
169+ return true ;
170+ }
171+ }
172+ return false ;
173+ }
174+
175+ private static String getJreSource (int javaVersion , String arch ){
176+ return String .format ("https://github.com/AngelAuraMC/angelauramc-openjdk-build/releases/download/download_jre%1$s/jre%1$s-android-%2$s.tar.xz" , javaVersion , arch );
177+ }
178+ /**
179+ * @return whether installation was successful or not
180+ */
181+ private static void tryDownloadRuntime (Context activity , int javaVersion ){
182+ if (!isOnline (activity )) throw new RuntimeException (activity .getString (R .string .multirt_no_internet ));
183+ String arch = archAsString (getDeviceArchitecture ());
184+ // Checks for using this method
185+ if (!isJavaVersionAvailableForDownload (javaVersion )) throw new RuntimeException ("This is not an available JRE version" );
186+ if ((getDeviceArchitecture () == Architecture .ARCH_X86 && javaVersion >= 21 )) throw new RuntimeException ("x86 is not supported on Java" +javaVersion );
187+ try {
188+ File outputFile = new File (Tools .DIR_CACHE , String .format ("jre%s-android-%s.tar.xz" , javaVersion , arch ));
189+ DownloaderProgressWrapper monitor = new DownloaderProgressWrapper (R .string .newdl_downloading_jre_runtime ,
190+ ProgressLayout .UNPACK_RUNTIME );
191+ monitor .extraString = Integer .toString (javaVersion );
192+ DownloadUtils .downloadFileMonitored (
193+ getJreSource (javaVersion , arch ),
194+ outputFile ,
195+ null ,
196+ monitor
197+ );
198+ String jreName = "External-" + javaVersion ;
199+ MultiRTUtils .installRuntimeNamed (NATIVE_LIB_DIR , new FileInputStream (outputFile ), jreName );
200+ MultiRTUtils .postPrepare (jreName );
201+ outputFile .delete ();
202+ } catch (IOException e ) {
203+ throw new RuntimeException ("Failed to download Java " +javaVersion +" for " +arch , e );
204+ }
205+ }
206+
144207 private enum InternalRuntime {
145208 JRE_17 (17 , "Internal-17" , "components/jre-new" ),
146209 JRE_21 (21 , "Internal-21" , "components/jre-21" ),
@@ -155,4 +218,24 @@ private enum InternalRuntime {
155218 }
156219 }
157220
221+ public enum ExternalRuntime {
222+ JRE_8 (8 , "External-8" ),
223+ JRE_17 (17 , "External-17" ),
224+ JRE_21 (21 , "External-21" ),
225+ JRE_25 (25 , "External-25" );
226+ public final int majorVersion ;
227+ public final String name ;
228+ public final String downloadLink ;
229+ public boolean isDownloading = false ;
230+
231+ ExternalRuntime (int majorVersion , String name ) {
232+ this .majorVersion = majorVersion ;
233+ this .name = name ;
234+ this .downloadLink = getJreSource (majorVersion , archAsString (getDeviceArchitecture ()));
235+ }
236+ public void downloadRuntime (Context activity ){
237+ tryDownloadRuntime (activity , majorVersion );
238+ }
239+ }
240+
158241}
0 commit comments