Skip to content

Commit

Permalink
Feat[gui_launcher]: refactor java selection and modify argument proce…
Browse files Browse the repository at this point in the history
…ssing
  • Loading branch information
artdeell committed Jul 27, 2024
1 parent 3912db6 commit 3b1ad64
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import android.widget.Toast;

import androidx.activity.OnBackPressedCallback;
import androidx.appcompat.app.AlertDialog;

import com.kdt.LoggerView;

Expand Down Expand Up @@ -185,6 +186,7 @@ private void startModInstallerWithUri(Uri uri) {
try {
File cacheFile = new File(getCacheDir(), "mod-installer-temp");
InputStream contentStream = getContentResolver().openInputStream(uri);
if(contentStream == null) throw new IOException("Failed to open content stream");
try (FileOutputStream fileOutputStream = new FileOutputStream(cacheFile)) {
IOUtils.copy(contentStream, fileOutputStream);
}
Expand All @@ -195,23 +197,69 @@ private void startModInstallerWithUri(Uri uri) {
}
}

public Runtime selectRuntime(File modFile) {
int javaVersion = getJavaVersion(modFile);
if(javaVersion == -1) {
finalErrorDialog(getString(R.string.execute_jar_failed_to_read_file));
return null;
}
String nearestRuntime = MultiRTUtils.getNearestJreName(javaVersion);
if(nearestRuntime == null) {
finalErrorDialog(getString(R.string.multirt_nocompatiblert, javaVersion));
return null;
}
Runtime selectedRuntime = MultiRTUtils.forceReread(nearestRuntime);
int selectedJavaVersion = Math.max(javaVersion, selectedRuntime.javaVersion);
if(selectedJavaVersion > 17) {
finalErrorDialog(getString(R.string.execute_jar_incompatible_runtime, selectedJavaVersion));
}
return selectedRuntime;
}

private File findModPath(List<String> argList) {
int argsSize = argList.size();
for(int i = 0; i < argsSize; i++) {
// Look for the -jar argument
if(!argList.get(i).equals("-jar")) continue;
int pathIndex = i+1;
// Check if the supposed path is out of the argument bounds
if(pathIndex >= argsSize) return null;
// Use the path as a file
return new File(argList.get(pathIndex));
}
return null;
}

private void startModInstaller(File modFile, String javaArgs) {
new Thread(() -> {
Runtime runtime = pickJreForMod(modFile);
launchJavaRuntime(runtime, modFile, javaArgs);
// Maybe replace with more advanced arg parsing logic later
List<String> argList = Arrays.asList(javaArgs.split(" "));
File selectedMod = modFile;
if(selectedMod == null) {
// If modFile is not specified directly, try to extract the -jar argument from the javaArgs
selectedMod = findModPath(argList);
}
Runtime selectedRuntime;
if(selectedMod == null) {
// We were unable to find out the path to the mod. In that case, use the default runtime.
selectedRuntime = MultiRTUtils.forceReread(LauncherPreferences.PREF_DEFAULT_RUNTIME);
}else {
// Autoselect it properly in the other case.
selectedRuntime = selectRuntime(selectedMod);
// If the selection failed, just return. The autoselect function has already shown the dialog.
if(selectedRuntime == null) return;
}
launchJavaRuntime(selectedRuntime, modFile, argList);
}, "JREMainThread").start();
}

private Runtime pickJreForMod(File modFile) {
String jreName = LauncherPreferences.PREF_DEFAULT_RUNTIME;
if(modFile != null) {
int javaVersion = getJavaVersion(modFile);
if(javaVersion != -1) {
String autoselectRuntime = MultiRTUtils.getNearestJreName(javaVersion);
if (autoselectRuntime != null) jreName = autoselectRuntime;
}
}
return MultiRTUtils.forceReread(jreName);
private void finalErrorDialog(CharSequence msg) {
runOnUiThread(()-> new AlertDialog.Builder(this)
.setTitle(R.string.global_error)
.setMessage(msg)
.setPositiveButton(android.R.string.ok, (d,w)->this.finish())
.setCancelable(false)
.show());
}

@Override
Expand Down Expand Up @@ -301,21 +349,19 @@ public void toggleVirtualMouse(View v) {
Toast.LENGTH_SHORT).show();
}

public void launchJavaRuntime(Runtime runtime, File modFile, String javaArgs) {
public void launchJavaRuntime(Runtime runtime, File modFile, List<String> javaArgs) {
JREUtils.redirectAndPrintJRELog();
try {
List<String> javaArgList = new ArrayList<>();

// Enable Caciocavallo
Tools.getCacioJavaArgs(javaArgList,runtime.javaVersion == 8);

if (javaArgs != null) {
javaArgList.addAll(Arrays.asList(javaArgs.split(" ")));
} else {

javaArgList.addAll(javaArgs);
if(modFile != null) {
javaArgList.add("-jar");
javaArgList.add(modFile.getAbsolutePath());
}


if (LauncherPreferences.PREF_JAVA_SANDBOX) {
Collections.reverse(javaArgList);
Expand Down Expand Up @@ -351,30 +397,36 @@ public void performPaste(View view) {
public int getJavaVersion(File modFile) {
try (ZipFile zipFile = new ZipFile(modFile)){
ZipEntry manifest = zipFile.getEntry("META-INF/MANIFEST.MF");
Log.i("JavaVersion", "Mf entry: "+manifest);
if(manifest == null) return -1;
Log.i("JavaVersion", "Found manifest entry");

String manifestString = Tools.read(zipFile.getInputStream(manifest));
String mainClass = Tools.extractUntilCharacter(manifestString, "Main-Class:", '\n');
if(mainClass == null) return -1;
Log.i("JavaVersion", "Found main class: "+mainClass);

mainClass = mainClass.trim().replace('.', '/') + ".class";
ZipEntry mainClassFile = zipFile.getEntry(mainClass);
if(mainClassFile == null) return -1;
Log.i("JavaVersion", "Found main class entry: "+mainClass);

InputStream classStream = zipFile.getInputStream(mainClassFile);
byte[] bytesWeNeed = new byte[8];
int readCount = classStream.read(bytesWeNeed);
classStream.close();
if(readCount < 8) return -1;
Log.i("JavaVersion", "File is long enough!");

ByteBuffer byteBuffer = ByteBuffer.wrap(bytesWeNeed);
if(byteBuffer.getInt() != 0xCAFEBABE) return -1;
Log.i("JavaVersion", "File is Java class!");
short minorVersion = byteBuffer.getShort();
short majorVersion = byteBuffer.getShort();
Log.i("JavaGUILauncher", majorVersion+","+minorVersion);
return classVersionToJavaVersion(majorVersion);
}catch (Exception e) {
e.printStackTrace();
Log.e("JavaVersion", "Exception thrown", e);
return -1;
}
}
Expand Down
4 changes: 3 additions & 1 deletion app_pojavlauncher/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@
<string name="multirt_config_setdefault">Set default</string>
<string name="multirt_config_setdefault_already">Default</string>
<string name="multirt_config_removeerror_last">You must have at least one Java Runtime installed.</string>
<string name="multirt_nocompatiblert">Can\'t find any compartible Java Runtime. This version requires Java %d or newer.</string>
<string name="multirt_nocompatiblert">Can\'t find any compatible Java Runtime. This version requires Java %d or newer.</string>
<string name="multirt_nojava8rt">Can\'t find Java 8. In order to use this option, you need to install Java 8.</string>
<string name="multirt_delete_runtime">Delete runtime</string>
<string name="pvc_gameDirectory">Game directory</string>
Expand Down Expand Up @@ -382,4 +382,6 @@
<string name="log_view_button_output_off">Output\nOFF</string>
<string name="log_view_button_output_on">Output\nON</string>
<string name="log_view_label_log_output">Log output:</string>
<string name="execute_jar_failed_to_read_file">Failed to read the .jar file</string>
<string name="execute_jar_incompatible_runtime">Execute .jar feature is not compatible with Java %d</string>
</resources>

0 comments on commit 3b1ad64

Please sign in to comment.