mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2026-04-20 09:37:07 -04:00
Feat[launcher]: ranked Java Runtime picking from two sources
This commit is contained in:
@@ -47,46 +47,89 @@ public class NewJREUtil {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static InternalRuntime getInternalRuntime(String s_runtime) {
|
||||
Runtime runtime = MultiRTUtils.read(s_runtime);
|
||||
if(runtime == null) return null;
|
||||
|
||||
private static InternalRuntime getInternalRuntime(Runtime runtime) {
|
||||
for(InternalRuntime internalRuntime : InternalRuntime.values()) {
|
||||
if(internalRuntime.name.equals(runtime.name)) return internalRuntime;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static InternalRuntime findAppropriateInternalRuntime(int targetVersion) {
|
||||
private static MathUtils.RankedValue<Runtime> getNearestInstalledRuntime(int targetVersion) {
|
||||
List<Runtime> runtimes = MultiRTUtils.getRuntimes();
|
||||
return MathUtils.findNearestPositive(targetVersion, runtimes, (runtime)->runtime.javaVersion);
|
||||
}
|
||||
|
||||
private static MathUtils.RankedValue<InternalRuntime> getNearestInternalRuntime(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;
|
||||
|
||||
int gameRequiredVersion = versionInfo.javaVersion.majorVersion;
|
||||
|
||||
LauncherProfiles.load();
|
||||
AssetManager assetManager = activity.getAssets();
|
||||
MinecraftProfile minecraftProfile = LauncherProfiles.getCurrentProfile();
|
||||
String selectedRuntime = Tools.getSelectedRuntime(minecraftProfile);
|
||||
Runtime runtime = MultiRTUtils.read(selectedRuntime);
|
||||
if (runtime.javaVersion >= versionInfo.javaVersion.majorVersion) {
|
||||
String profileRuntime = Tools.getSelectedRuntime(minecraftProfile);
|
||||
Runtime runtime = MultiRTUtils.read(profileRuntime);
|
||||
// Partly trust the user with his own selection, if the game can even try to run in this case
|
||||
if (runtime.javaVersion >= gameRequiredVersion) {
|
||||
// Check whether the selection is an internal runtime
|
||||
InternalRuntime internalRuntime = getInternalRuntime(runtime);
|
||||
// If it is, check if updates are available from the APK file
|
||||
if(internalRuntime != null) {
|
||||
// Not calling showRuntimeFail on failure here because we did, technically, find the compatible runtime
|
||||
return checkInternalRuntime(assetManager, internalRuntime);
|
||||
}
|
||||
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 the runtime version selected by the user is not appropriate for this version (which means the game won't run at all)
|
||||
// automatically pick from either an already installed runtime, or a runtime packed with the launcher
|
||||
MathUtils.RankedValue<Runtime> nearestInstalledRuntime = getNearestInstalledRuntime(gameRequiredVersion);
|
||||
MathUtils.RankedValue<InternalRuntime> nearestInternalRuntime = getNearestInternalRuntime(gameRequiredVersion);
|
||||
|
||||
MathUtils.RankedValue<?> selectedRankedRuntime = (MathUtils.RankedValue<?>) MathUtils.multiTypeObjectMin(
|
||||
nearestInternalRuntime, nearestInstalledRuntime,
|
||||
(v1)->v1.rank,
|
||||
(v2)->v2.rank
|
||||
);
|
||||
|
||||
// No possible selections
|
||||
if(selectedRankedRuntime == null) {
|
||||
showRuntimeFail(activity, versionInfo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if((internalRuntime == null || !NewJREUtil.checkInternalRuntime(activity.getAssets(), internalRuntime)) && failOnMiss) {
|
||||
showRuntimeFail(activity, versionInfo);
|
||||
Object selected = selectedRankedRuntime.value;
|
||||
String appropriateRuntime;
|
||||
InternalRuntime internalRuntime;
|
||||
|
||||
// Perform checks on the picked runtime
|
||||
if(selected instanceof Runtime) {
|
||||
// If it's an already installed runtime, save its name and check if
|
||||
// it's actually an internal one (just in case)
|
||||
Runtime selectedRuntime = (Runtime) selected;
|
||||
appropriateRuntime = selectedRuntime.name;
|
||||
internalRuntime = getInternalRuntime(selectedRuntime);
|
||||
} else if (selected instanceof InternalRuntime) {
|
||||
// If it's an internal runtime, set it's name as the appropriate one.
|
||||
internalRuntime = (InternalRuntime) selected;
|
||||
appropriateRuntime = internalRuntime.name;
|
||||
} else {
|
||||
throw new RuntimeException("Unexpected type of selected: "+selected.getClass().getName());
|
||||
}
|
||||
|
||||
// If it turns out the selected runtime is actually an internal one, attempt automatic installation or update
|
||||
if(internalRuntime != null && !checkInternalRuntime(assetManager, internalRuntime)) {
|
||||
// Not calling showRuntimeFail here because we did, technically, find the compatible runtime
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,9 @@ public class MultiRTUtils {
|
||||
|
||||
public static String getNearestJreName(int majorVersion) {
|
||||
List<Runtime> runtimes = getRuntimes();
|
||||
Runtime nearestRuntime = MathUtils.findNearestPositive(majorVersion, runtimes, (runtime)->runtime.javaVersion);
|
||||
MathUtils.RankedValue<Runtime> nearestRankedRuntime = MathUtils.findNearestPositive(majorVersion, runtimes, (runtime)->runtime.javaVersion);
|
||||
if(nearestRankedRuntime == null) return null;
|
||||
Runtime nearestRuntime = nearestRankedRuntime.value;
|
||||
if(nearestRuntime == null) return null;
|
||||
return nearestRuntime.name;
|
||||
}
|
||||
|
||||
@@ -21,11 +21,11 @@ public class MathUtils {
|
||||
* @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
|
||||
* @return the RankedValue that wraps 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) {
|
||||
public static <T> RankedValue<T> findNearestPositive(int targetValue, List<T> objects, ValueProvider<T> valueProvider) {
|
||||
int delta = Integer.MAX_VALUE;
|
||||
T selectedObject = null;
|
||||
for(T object : objects) {
|
||||
@@ -33,16 +33,49 @@ public class MathUtils {
|
||||
if(objectValue < targetValue) continue;
|
||||
|
||||
int currentDelta = objectValue - targetValue;
|
||||
if(currentDelta == 0) return object;
|
||||
if(currentDelta == 0) return new RankedValue<>(object, 0);
|
||||
if(currentDelta >= delta) continue;
|
||||
|
||||
selectedObject = object;
|
||||
delta = currentDelta;
|
||||
}
|
||||
return selectedObject;
|
||||
if(selectedObject == null) return null;
|
||||
return new RankedValue<>(selectedObject, delta);
|
||||
}
|
||||
|
||||
public interface ValueProvider<T> {
|
||||
int getValue(T object);
|
||||
}
|
||||
|
||||
public static final class RankedValue<T> {
|
||||
public final T value;
|
||||
public final int rank;
|
||||
public RankedValue(T value, int rank) {
|
||||
this.value = value;
|
||||
this.rank = rank;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Out of two objects with different types, select one with the lowest value.
|
||||
* @param object1 Object 1 for comparsion
|
||||
* @param object2 Object 2 for comparsion
|
||||
* @param valueProvider1 Value provider for object 1
|
||||
* @param valueProvider2 Value provider for object 2
|
||||
* @return If value of object 1 is lower than or equal to object 2, returns object 1
|
||||
* Otherwise, returns object 2
|
||||
* @param <T> Type of object 1
|
||||
* @param <Y> Type of object 2
|
||||
*/
|
||||
public static <T,Y> Object multiTypeObjectMin(T object1, Y object2, ValueProvider<T> valueProvider1, ValueProvider<Y> valueProvider2) {
|
||||
if(object1 == null) return object2;
|
||||
if(object2 == null) return object1;
|
||||
int value1 = valueProvider1.getValue(object1);
|
||||
int value2 = valueProvider2.getValue(object2);
|
||||
if(value1 <= value2) {
|
||||
return object1;
|
||||
} else {
|
||||
return object2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user