mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-08-03 07:36:31 -04:00
Feat[jre_unpack]: add the ability to include multiple integrated runtimes
This commit is contained in:
parent
0797b7942e
commit
eccef88183
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@
|
||||
/build
|
||||
/*/build
|
||||
app_pojavlauncher/src/main/assets/components/jre
|
||||
/app_pojavlauncher/src/main/assets/components/jre-new/
|
||||
local.properties
|
||||
.idea/
|
||||
app_pojavlauncher/.cxx/
|
||||
|
@ -1,98 +0,0 @@
|
||||
package net.kdt.pojavlaunch;
|
||||
|
||||
import static net.kdt.pojavlaunch.Architecture.archAsString;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.res.AssetManager;
|
||||
import android.util.Log;
|
||||
|
||||
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
|
||||
import net.kdt.pojavlaunch.multirt.Runtime;
|
||||
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
|
||||
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class JRE17Util {
|
||||
public static final String NEW_JRE_NAME = "Internal-17";
|
||||
public static boolean checkInternalNewJre(AssetManager assetManager) {
|
||||
String launcher_jre17_version;
|
||||
String installed_jre17_version = MultiRTUtils.__internal__readBinpackVersion(NEW_JRE_NAME);
|
||||
try {
|
||||
launcher_jre17_version = Tools.read(assetManager.open("components/jre-new/version"));
|
||||
}catch (IOException exc) {
|
||||
//we don't have a runtime included!
|
||||
return installed_jre17_version != null; //if we have one installed -> return true -> proceed (no updates but the current one should be functional)
|
||||
//if we don't -> return false -> Cannot find compatible Java runtime
|
||||
}
|
||||
if(!launcher_jre17_version.equals(installed_jre17_version)) // this implicitly checks for null, so it will unpack the runtime even if we don't have one installed
|
||||
return unpackJre17(assetManager, launcher_jre17_version);
|
||||
else return true;
|
||||
}
|
||||
|
||||
private static boolean unpackJre17(AssetManager assetManager, String rt_version) {
|
||||
try {
|
||||
MultiRTUtils.installRuntimeNamedBinpack(
|
||||
assetManager.open("components/jre-new/universal.tar.xz"),
|
||||
assetManager.open("components/jre-new/bin-" + archAsString(Tools.DEVICE_ARCHITECTURE) + ".tar.xz"),
|
||||
"Internal-17", rt_version);
|
||||
MultiRTUtils.postPrepare("Internal-17");
|
||||
return true;
|
||||
}catch (IOException e) {
|
||||
Log.e("JRE17Auto", "Internal JRE unpack failed", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static boolean isInternalNewJRE(String s_runtime) {
|
||||
Runtime runtime = MultiRTUtils.read(s_runtime);
|
||||
if(runtime == null) return false;
|
||||
return NEW_JRE_NAME.equals(runtime.name);
|
||||
}
|
||||
|
||||
/** @return true if everything is good, false otherwise. */
|
||||
public static boolean installNewJreIfNeeded(Activity activity, JMinecraftVersionList.Version versionInfo) {
|
||||
//Now we have the reliable information to check if our runtime settings are good enough
|
||||
if (versionInfo.javaVersion == null || versionInfo.javaVersion.component.equalsIgnoreCase("jre-legacy"))
|
||||
return true;
|
||||
|
||||
LauncherProfiles.load();
|
||||
MinecraftProfile minecraftProfile = LauncherProfiles.getCurrentProfile();
|
||||
|
||||
String selectedRuntime = Tools.getSelectedRuntime(minecraftProfile);
|
||||
|
||||
Runtime runtime = MultiRTUtils.read(selectedRuntime);
|
||||
if (runtime.javaVersion >= versionInfo.javaVersion.majorVersion) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String appropriateRuntime = MultiRTUtils.getNearestJreName(versionInfo.javaVersion.majorVersion);
|
||||
if (appropriateRuntime != null) {
|
||||
if (JRE17Util.isInternalNewJRE(appropriateRuntime)) {
|
||||
JRE17Util.checkInternalNewJre(activity.getAssets());
|
||||
}
|
||||
minecraftProfile.javaDir = Tools.LAUNCHERPROFILES_RTPREFIX + appropriateRuntime;
|
||||
LauncherProfiles.load();
|
||||
} else {
|
||||
if (versionInfo.javaVersion.majorVersion <= 17) { // there's a chance we have an internal one for this case
|
||||
if (!JRE17Util.checkInternalNewJre(activity.getAssets())){
|
||||
showRuntimeFail(activity, versionInfo);
|
||||
return false;
|
||||
} else {
|
||||
minecraftProfile.javaDir = Tools.LAUNCHERPROFILES_RTPREFIX + JRE17Util.NEW_JRE_NAME;
|
||||
LauncherProfiles.load();
|
||||
}
|
||||
} else {
|
||||
showRuntimeFail(activity, versionInfo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void showRuntimeFail(Activity activity, JMinecraftVersionList.Version verInfo) {
|
||||
Tools.dialogOnUiThread(activity, activity.getString(R.string.global_error),
|
||||
activity.getString(R.string.multirt_nocompartiblert, verInfo.javaVersion.majorVersion));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
package net.kdt.pojavlaunch;
|
||||
|
||||
import static net.kdt.pojavlaunch.Architecture.archAsString;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.res.AssetManager;
|
||||
import android.util.Log;
|
||||
|
||||
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
|
||||
import net.kdt.pojavlaunch.multirt.Runtime;
|
||||
import net.kdt.pojavlaunch.utils.MathUtils;
|
||||
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
|
||||
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class NewJREUtil {
|
||||
private static boolean checkInternalRuntime(AssetManager assetManager, InternalRuntime internalRuntime) {
|
||||
String launcher_runtime_version;
|
||||
String installed_runtime_version = MultiRTUtils.readInternalRuntimeVersion(internalRuntime.name);
|
||||
try {
|
||||
launcher_runtime_version = Tools.read(assetManager.open(internalRuntime.path+"/version"));
|
||||
}catch (IOException exc) {
|
||||
//we don't have a runtime included!
|
||||
//if we have one installed -> return true -> proceed (no updates but the current one should be functional)
|
||||
//if we don't -> return false -> Cannot find compatible Java runtime
|
||||
return installed_runtime_version != null;
|
||||
}
|
||||
// this implicitly checks for null, so it will unpack the runtime even if we don't have one installed
|
||||
if(!launcher_runtime_version.equals(installed_runtime_version))
|
||||
return unpackInternalRuntime(assetManager, internalRuntime, launcher_runtime_version);
|
||||
else return true;
|
||||
}
|
||||
|
||||
private static boolean unpackInternalRuntime(AssetManager assetManager, InternalRuntime internalRuntime, String version) {
|
||||
try {
|
||||
MultiRTUtils.installRuntimeNamedBinpack(
|
||||
assetManager.open(internalRuntime.path+"/universal.tar.xz"),
|
||||
assetManager.open(internalRuntime.path+"/bin-" + archAsString(Tools.DEVICE_ARCHITECTURE) + ".tar.xz"),
|
||||
internalRuntime.name, version);
|
||||
MultiRTUtils.postPrepare(internalRuntime.name);
|
||||
return true;
|
||||
}catch (IOException e) {
|
||||
Log.e("NewJREAuto", "Internal JRE unpack failed", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static InternalRuntime getInternalRuntime(String s_runtime) {
|
||||
Runtime runtime = MultiRTUtils.read(s_runtime);
|
||||
if(runtime == null) return null;
|
||||
for(InternalRuntime internalRuntime : InternalRuntime.values()) {
|
||||
if(internalRuntime.name.equals(runtime.name)) return internalRuntime;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static InternalRuntime findAppropriateInternalRuntime(int targetVersion) {
|
||||
List<InternalRuntime> runtimeList = Arrays.asList(InternalRuntime.values());
|
||||
return MathUtils.findNearestPositive(targetVersion, runtimeList, (runtime)->runtime.majorVersion);
|
||||
}
|
||||
|
||||
/** @return true if everything is good, false otherwise. */
|
||||
public static boolean installNewJreIfNeeded(Activity activity, JMinecraftVersionList.Version versionInfo) {
|
||||
//Now we have the reliable information to check if our runtime settings are good enough
|
||||
if (versionInfo.javaVersion == null || versionInfo.javaVersion.component.equalsIgnoreCase("jre-legacy"))
|
||||
return true;
|
||||
|
||||
LauncherProfiles.load();
|
||||
MinecraftProfile minecraftProfile = LauncherProfiles.getCurrentProfile();
|
||||
String selectedRuntime = Tools.getSelectedRuntime(minecraftProfile);
|
||||
Runtime runtime = MultiRTUtils.read(selectedRuntime);
|
||||
if (runtime.javaVersion >= versionInfo.javaVersion.majorVersion) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String appropriateRuntime = MultiRTUtils.getNearestJreName(versionInfo.javaVersion.majorVersion);
|
||||
boolean failOnMiss = false;
|
||||
InternalRuntime internalRuntime;
|
||||
if(appropriateRuntime == null) {
|
||||
internalRuntime = NewJREUtil.findAppropriateInternalRuntime(versionInfo.javaVersion.majorVersion);
|
||||
failOnMiss = true;
|
||||
}else {
|
||||
internalRuntime = NewJREUtil.getInternalRuntime(appropriateRuntime);
|
||||
}
|
||||
|
||||
if((internalRuntime == null || !NewJREUtil.checkInternalRuntime(activity.getAssets(), internalRuntime)) && failOnMiss) {
|
||||
showRuntimeFail(activity, versionInfo);
|
||||
return false;
|
||||
}
|
||||
|
||||
minecraftProfile.javaDir = Tools.LAUNCHERPROFILES_RTPREFIX + appropriateRuntime;
|
||||
LauncherProfiles.write();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void showRuntimeFail(Activity activity, JMinecraftVersionList.Version verInfo) {
|
||||
Tools.dialogOnUiThread(activity, activity.getString(R.string.global_error),
|
||||
activity.getString(R.string.multirt_nocompartiblert, verInfo.javaVersion.majorVersion));
|
||||
}
|
||||
|
||||
private enum InternalRuntime {
|
||||
JRE_17(17, "Internal-17", "components/jre-new");
|
||||
public final int majorVersion;
|
||||
public final String name;
|
||||
public final String path;
|
||||
InternalRuntime(int majorVersion, String name, String path) {
|
||||
this.majorVersion = majorVersion;
|
||||
this.name = name;
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -10,6 +10,7 @@ import com.kdt.mcgui.ProgressLayout;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
import net.kdt.pojavlaunch.utils.MathUtils;
|
||||
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
@ -60,19 +61,9 @@ public class MultiRTUtils {
|
||||
|
||||
public static String getNearestJreName(int majorVersion) {
|
||||
List<Runtime> runtimes = getRuntimes();
|
||||
int diff_factor = Integer.MAX_VALUE;
|
||||
String result = null;
|
||||
for(Runtime r : runtimes) {
|
||||
if(r.javaVersion < majorVersion) continue; // lower - not useful
|
||||
|
||||
int currentFactor = r.javaVersion - majorVersion;
|
||||
if(diff_factor > currentFactor) {
|
||||
result = r.name;
|
||||
diff_factor = currentFactor;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
Runtime nearestRuntime = MathUtils.findNearestPositive(majorVersion, runtimes, (runtime)->runtime.javaVersion);
|
||||
if(nearestRuntime == null) return null;
|
||||
return nearestRuntime.name;
|
||||
}
|
||||
|
||||
public static void installRuntimeNamed(String nativeLibDir, InputStream runtimeInputStream, String name) throws IOException {
|
||||
@ -120,11 +111,11 @@ public class MultiRTUtils {
|
||||
}
|
||||
|
||||
|
||||
public static String __internal__readBinpackVersion(String name) {
|
||||
File binpack_verfile = new File(RUNTIME_FOLDER,"/" + name + "/pojav_version");
|
||||
public static String readInternalRuntimeVersion(String name) {
|
||||
File versionFile = new File(RUNTIME_FOLDER,"/" + name + "/pojav_version");
|
||||
try {
|
||||
if (binpack_verfile.exists()) {
|
||||
return Tools.read(binpack_verfile.getAbsolutePath());
|
||||
if (versionFile.exists()) {
|
||||
return Tools.read(versionFile.getAbsolutePath());
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public class AsyncAssetManager {
|
||||
public static void unpackRuntime(AssetManager am) {
|
||||
/* Check if JRE is included */
|
||||
String rt_version = null;
|
||||
String current_rt_version = MultiRTUtils.__internal__readBinpackVersion("Internal");
|
||||
String current_rt_version = MultiRTUtils.readInternalRuntimeVersion("Internal");
|
||||
try {
|
||||
rt_version = Tools.read(am.open("components/jre/version"));
|
||||
} catch (IOException e) {
|
||||
|
@ -13,7 +13,7 @@ import com.kdt.mcgui.ProgressLayout;
|
||||
import net.kdt.pojavlaunch.JAssetInfo;
|
||||
import net.kdt.pojavlaunch.JAssets;
|
||||
import net.kdt.pojavlaunch.JMinecraftVersionList;
|
||||
import net.kdt.pojavlaunch.JRE17Util;
|
||||
import net.kdt.pojavlaunch.NewJREUtil;
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
import net.kdt.pojavlaunch.mirrors.DownloadMirror;
|
||||
@ -203,7 +203,7 @@ public class MinecraftDownloader {
|
||||
throw new IOException("Unable to read Version JSON for version " + versionName);
|
||||
}
|
||||
|
||||
if(activity != null && !JRE17Util.installNewJreIfNeeded(activity, verInfo)){
|
||||
if(activity != null && !NewJREUtil.installNewJreIfNeeded(activity, verInfo)){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.kdt.pojavlaunch.utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MathUtils {
|
||||
|
||||
//Ported from https://www.arduino.cc/reference/en/language/functions/math/map/
|
||||
@ -14,4 +16,33 @@ public class MathUtils {
|
||||
return (float) Math.hypot(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the object T with the closest (or higher) value compared to targetValue
|
||||
* @param targetValue the target value
|
||||
* @param objects the list of objects that the search will be performed on
|
||||
* @param valueProvider the provider for each values
|
||||
* @return the object which has the closest value to targetValue, or null if values of all
|
||||
* objects are less than targetValue
|
||||
* @param <T> the object type that is used for the search.
|
||||
*/
|
||||
public static <T> T findNearestPositive(int targetValue, List<T> objects, ValueProvider<T> valueProvider) {
|
||||
int delta = Integer.MAX_VALUE;
|
||||
T selectedObject = null;
|
||||
for(T object : objects) {
|
||||
int objectValue = valueProvider.getValue(object);
|
||||
if(objectValue < targetValue) continue;
|
||||
|
||||
int currentDelta = objectValue - targetValue;
|
||||
if(currentDelta == 0) return object;
|
||||
if(currentDelta >= delta) continue;
|
||||
|
||||
selectedObject = object;
|
||||
delta = currentDelta;
|
||||
}
|
||||
return selectedObject;
|
||||
}
|
||||
|
||||
public interface ValueProvider<T> {
|
||||
int getValue(T object);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user