Skip to content

Commit

Permalink
Feat[jre_unpack]: add the ability to include multiple integrated runt…
Browse files Browse the repository at this point in the history
…imes
  • Loading branch information
artdeell committed Jun 14, 2024
1 parent bdc7f33 commit b12429b
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 118 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand Down
98 changes: 0 additions & 98 deletions app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JRE17Util.java

This file was deleted.

115 changes: 115 additions & 0 deletions app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/NewJREUtil.java
Original file line number Diff line number Diff line change
@@ -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;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

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;
Expand Down Expand Up @@ -60,19 +61,9 @@ public static String getExactJreName(int majorVersion) {

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 {
Expand Down Expand Up @@ -120,11 +111,11 @@ public static void installRuntimeNamedBinpack(InputStream universalFileInputStre
}


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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ private 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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
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;
Expand Down Expand Up @@ -203,7 +203,7 @@ private boolean downloadAndProcessMetadata(Activity activity, JMinecraftVersionL
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;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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/
Expand All @@ -14,4 +16,33 @@ public static float dist(float x1, float y1, float x2, float y2) {
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);
}
}

0 comments on commit b12429b

Please sign in to comment.