Add mod installer (not implemented)

This commit is contained in:
khanhduytran0 2020-09-01 07:32:54 +07:00
parent bf49d40eb7
commit 958e22f0a3
9 changed files with 176 additions and 243 deletions

View File

@ -41,6 +41,11 @@
android:name=".MCLauncherActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity
android:screenOrientation="sensorLandscape"
android:name=".InstallModActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity
android:screenOrientation="sensorLandscape"
android:name=".CustomControlsActivity"

View File

@ -28,12 +28,32 @@ public class BinaryExecutor
// return fd;
}
public static void setJavaEnvironment() {
setEnvironment("JAVA_HOME", Tools.homeJreDir);
setEnvironment("HOME", Tools.MAIN_PATH);
setEnvironment("TMPDIR", getCacheDir().getAbsolutePath());
// setEnvironment("LIBGL_MIPMAP", "3");
setEnvironment("MESA_GLSL_CACHE_DIR", getCacheDir().getAbsolutePath());
setEnvironment("LD_LIBRARY_PATH", ldLibraryPath);
setEnvironment("PATH", Tools.homeJreDir + "/bin:" + Os.getenv("PATH"));
}
private static void setEnvironment(String name, String value) throws ErrnoException, IOException {
if (MainActivity.LAUNCH_TYPE == MainActivity.LTYPE_PROCESS) {
mLaunchShell.writeToProcess("export " + name + "=" + value);
} else {
Os.setenv(name, value, true);
}
}
public static native int chdir(String path);
public static native boolean dlopen(String libPath);
public static native void setLdLibraryPath(String ldLibraryPath);
public static native void setupBridgeEGL();
public static native void setupBridgeSurfaceAWT(Object surface);
// BEFORE Load and execute PIE binary using dlopen and dlsym("main")
// AFTER: Execute a binary in forked process
public static native int executeBinary(String[] args);

View File

@ -0,0 +1,98 @@
package net.kdt.pojavlaunch;
import android.graphics.*;
import android.os.*;
import android.support.v7.app.*;
import android.view.*;
import com.oracle.dalvik.*;
import java.io.*;
import java.util.*;
public class InstallModActivity extends AppCompatActivity
{
private TextureView mTextureView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.install_mod);
final File modFile = (File) getIntent().getExtras().getSerializable("modFile");
mTextureView = findViewById(R.id.installmod_surfaceview);
mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener(){
@Override
public void onSurfaceTextureAvailable(SurfaceTexture tex, int w, int h) {
BinaryExecutor.setupBridgeSurfaceAWT(new Surface(tex));
new Thread(new Runnable(){
@Override
public void run() {
launchJavaRuntime(modFile);
finish();
}
}).start();
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture tex) {
return false;
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture tex, int w, int h) {
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture tex) {
}
});
}
public void forceClose(View v) {
MainActivity.dialogForceClose(this);
}
private void launchJavaRuntime(File modFile) {
try {
List<String> javaArgList = new ArrayList<String>();
javaArgList.add(Tools.homeJreDir + "/bin/java");
// javaArgList.add("-Xms512m");
javaArgList.add("-Xmx512m");
javaArgList.add("-Djava.home=" + Tools.homeJreDir);
javaArgList.add("-Dos.name=Linux");
javaArgList.add("-Djava.library.path=");
javaArgList.add("-jar");
javaArgList.add(modFile.getAbsolutePath());
String libName = System.getProperty("os.arch").contains("64") ? "lib64" : "lib";
String ldLibraryPath = (
// To make libjli.so ignore re-execute
Tools.homeJreDir + "/lib/server:" +
"/system/" + libName + ":" +
"/vendor/" + libName + ":" +
"/vendor/" + libName + "/hw:" +
getApplicationInfo().nativeLibraryDir + ":" +
Tools.homeJreDir + "/lib/jli:" +
Tools.homeJreDir + "/lib"
);
BinaryExecutor.setJavaEnvironment();
BinaryExecutor.redirectStdio();
BinaryExecutor.setLdLibraryPath(ldLibraryPath);
BinaryExecutor.initJavaRuntime();
BinaryExecutor.chdir(Tools.MAIN_PATH);
VMLauncher.launchJVM(javaArgList.toArray(new String[0]));
} catch (Throwable th) {
Tools.showError(this, th, true);
}
}
}

View File

@ -773,21 +773,18 @@ public class MCLauncherActivity extends AppCompatActivity
@Override
public void onClick(DialogInterface p1, int p2)
{
switch(p2){
case 0:{ // Mods manager
modManager();
} break;
case 1:{ // OptiFine installer
installOptiFine();
} break;
case 2:{ // Custom controls
if (Tools.enableDevFeatures) {
startActivity(new Intent(MCLauncherActivity.this, CustomControlsActivity.class));
}
} break;
case 3:{ // Settings
startActivity(new Intent(MCLauncherActivity.this, LauncherPreferenceActivity.class));
} break;
switch (p2) {
case 1: // Mod installer
installMod();
break;
case 2: // Custom controls
if (Tools.enableDevFeatures) {
startActivity(new Intent(MCLauncherActivity.this, CustomControlsActivity.class));
}
break;
case 3: // Settings
startActivity(new Intent(MCLauncherActivity.this, LauncherPreferenceActivity.class));
break;
case 4:{ // About
final AlertDialog.Builder aboutB = new AlertDialog.Builder(MCLauncherActivity.this);
aboutB.setTitle(R.string.mcl_option_about);
@ -810,70 +807,11 @@ public class MCLauncherActivity extends AppCompatActivity
builder.show();
}
public void modManager()
{
/*
File file1 = new File(Tools.mpModEnable);
File file2 = new File(Tools.mpModDisable);
File file3 = new File(Tools.mpModAddNewMo);
file1.mkdirs();
file2.mkdir();
try
{
file3.createNewFile();
}
catch (IOException e){}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Mods manager (Forge)");
builder.setPositiveButton(android.R.string.cancel, null);
AlertDialog dialog = builder.create();
MFileListView flv = new MFileListView(this, dialog);
flv.listFileAt(Tools.datapath + "/ModsManager");
flv.setFileSelectedListener(new MFileSelectedListener(){
@Override
public void onFileLongClick(File file, String path, String nane, String extension)
{
// TODO: Implement this method
}
@Override
public void onFileSelected(File file, String path, String nane, String extension)
{
// TODO: Implement this method
if(extension.equals(".jar")) {
} else {
openSelectMod();
}
}
});
dialog.setView(flv);
dialog.show();
*/
Tools.dialogOnUiThread(this, "Mods manager", "This feature is not yet supported!");
}
public void openSelectMod()
{
private void installMod() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.alerttitle_installmod);
builder.setPositiveButton(android.R.string.cancel, null);
AlertDialog dialog = builder.create();
FileListView flv = new FileListView(this);
dialog.setView(flv);
dialog.show();
}
private void installOptiFine() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.alerttitle_installoptifine);
builder.setPositiveButton(android.R.string.cancel, null);
final AlertDialog dialog = builder.create();
FileListView flv = new FileListView(this);
flv.setFileSelectedListener(new FileSelectedListener(){
@ -881,7 +819,9 @@ public class MCLauncherActivity extends AppCompatActivity
@Override
public void onFileSelected(File file, String path, String name) {
if (name.endsWith(".jar")) {
doInstallOptiFine(file);
Intent intent = new Intent(MCLauncherActivity.this, InstallModActivity.class);
intent.putExtra("modFile", file);
startActivity(intent);
dialog.dismiss();
}
}
@ -890,143 +830,6 @@ public class MCLauncherActivity extends AppCompatActivity
dialog.show();
}
private void doInstallOptiFine(File optifineFile) {
new OptiFineInstaller().execute(optifineFile);
}
private class OptiFineInstaller extends AsyncTask<File, String, Throwable>
{
private ProgressDialog dialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(MCLauncherActivity.this);
dialog.setTitle("Installing OptiFine");
dialog.setMessage("Preparing");
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMax(5);
dialog.setCancelable(false);
dialog.show();
}
@Override
protected Throwable doInBackground(File[] file) {
final StringBuilder currentLog = new StringBuilder();
LoggerJava.LoggerOutputStream logOut = new LoggerJava.LoggerOutputStream(System.out, new LoggerJava.OnStringPrintListener(){
@Override
public void onCharPrint(char c)
{
currentLog.append(c);
}
});
LoggerJava.LoggerOutputStream logErr = new LoggerJava.LoggerOutputStream(System.err, new LoggerJava.OnStringPrintListener(){
@Override
public void onCharPrint(char c)
{
currentLog.append(c);
}
});
Throwable throwable = null;
File convertedFile = null;
try {
publishProgress("Preparing", "5");
String origMd5 = OptiFinePatcher.calculateMD5(file[0]);
convertedFile = new File(Tools.optifineDir, origMd5 + ".jar");
if (!convertedFile.exists()) {
publishProgress("Patching OptiFine Installer", null, "1", "true");
Tools.extractAssetFolder(MCLauncherActivity.this, "optifine_patch", Tools.optifineDir, true);
new File(Tools.optifineDir + "/optifine_patch/AndroidOptiFineUtilities.class.patch").delete();
String[] output = Tools.patchOptifineInstaller(MCLauncherActivity.this, file[0]);
File patchedFile = new File(output[1]);
publishProgress("Converting OptiFine", null, null, "false");
System.setOut(new PrintStream(logOut));
System.setErr(new PrintStream(logErr));
if (!convertedFile.exists()) {
RuntimeException dxError = new RuntimeException(getResources().getString(R.string.error_convert_lib, "OptiFine") + "\n" + currentLog.toString());
dxError.setStackTrace(new StackTraceElement[0]);
throw dxError;
}
patchedFile.delete();
}
publishProgress("Launching OptiFine installer", null, null, "true");
File optDir = getDir("dalvik-cache", 0);
optDir.mkdir();
DexClassLoader loader = new DexClassLoader(convertedFile.getAbsolutePath(), optDir.getAbsolutePath(), getApplicationInfo().nativeLibraryDir, getClass().getClassLoader());
// AndroidOptiFineUtilities.originalOptifineJar = convertedFile.getAbsolutePath();
Class installerClass = loader.loadClass("optifine.AndroidInstaller");
Method installerMethod = installerClass.getDeclaredMethod("doInstall", File.class);
installerMethod.invoke(null, new File(Tools.MAIN_PATH));
publishProgress("(4/5) Patching OptiFine Tweaker", null, null);
File optifineLibFile = new File("unimpl");
if (!optifineLibFile.exists()) {
throw new FileNotFoundException(optifineLibFile.getAbsolutePath() + "\n\n--- OptiFine installer log ---\n" + currentLog.toString());
}
new OptiFinePatcher(optifineLibFile).saveTweaker();
convertedFile.delete();
publishProgress("(5/5) Done!", null, null);
Thread.sleep(500);
} catch (Throwable th) {
throwable = th;
} finally {
System.setOut(logOut.getRootStream());
System.setErr(logErr.getRootStream());
/*
if (throwable != null && convertedFile != null) {
convertedFile.delete();
}
*/
return throwable;
}
}
/*
private Object fromConfig(DexClassLoader loader, String name) throws ReflectiveOperationException {
Field f = loader.loadClass("Config").getDeclaredField(name);
f.setAccessible(true);
return f.get(null);
}
*/
@Override
protected void onProgressUpdate(String[] text) {
super.onProgressUpdate(text);
dialog.setMessage(text[0]);
if (text.length > 1 && text[1] != null) {
dialog.setMax(Integer.valueOf(text[1]));
} if (text.length > 2) {
dialog.setProgress(dialog.getProgress() + 1);
} if (text.length > 3 && text[3] != null) {
dialog.setIndeterminate(Boolean.getBoolean(text[3]));
}
}
@Override
protected void onPostExecute(Throwable th) {
super.onPostExecute(th);
dialog.dismiss();
new RefreshVersionListTask().execute();
if (th == null) {
Toast.makeText(MCLauncherActivity.this, R.string.toast_optifine_success, Toast.LENGTH_SHORT).show();
} else {
Tools.showError(MCLauncherActivity.this, th);
}
}
}
private class ViewPagerAdapter extends FragmentPagerAdapter {
List<Fragment> fragmentList = new ArrayList<>();

View File

@ -123,10 +123,10 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
private boolean isLogAllow = false;
// private int navBarHeight = 40;
private static final int LTYPE_PROCESS = 0;
private static final int LTYPE_INVOCATION = 1;
private static final int LTYPE_CREATEJAVAVM = 2;
private static final int LAUNCH_TYPE;
public static final int LTYPE_PROCESS = 0;
public static final int LTYPE_INVOCATION = 1;
public static final int LTYPE_CREATEJAVAVM = 2;
public static final int LAUNCH_TYPE;
static {
int launchTypeFinal = LTYPE_INVOCATION;
@ -214,7 +214,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.nav_forceclose: dialogForceClose();
case R.id.nav_forceclose: dialogForceClose(MainActivity.this);
break;
case R.id.nav_viewlog: openLogOutput();
break;
@ -949,13 +949,6 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
}
private ShellProcessOperation mLaunchShell;
private void setEnvironment(String name, String value) throws ErrnoException, IOException {
if (LAUNCH_TYPE == LTYPE_PROCESS) {
mLaunchShell.writeToProcess("export " + name + "=" + value);
} else {
Os.setenv(name, value, true);
}
}
private static void startStrace(int pid) throws Exception {
String[] straceArgs = new String[] {"/system/bin/strace",
@ -1054,13 +1047,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
// "$JAVA_HOME/lib:$JAVA_HOME/lib/jli:$JAVA_HOME/lib/server"
);
setEnvironment("JAVA_HOME", Tools.homeJreDir);
setEnvironment("HOME", Tools.MAIN_PATH);
setEnvironment("TMPDIR", getCacheDir().getAbsolutePath());
// setEnvironment("LIBGL_MIPMAP", "3");
setEnvironment("MESA_GLSL_CACHE_DIR", getCacheDir().getAbsolutePath());
setEnvironment("LD_LIBRARY_PATH", ldLibraryPath);
setEnvironment("PATH", Tools.homeJreDir + "/bin:" + Os.getenv("PATH"));
BinaryExecutor.setJavaEnvironment();
// can fix java?
// setEnvironment("ORIGIN", Tools.homeJreDir + "/lib");
@ -1082,6 +1069,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
BinaryExecutor.redirectStdio();
// DEPRECATED constructor (String) api 29
/*
FileObserver fobs = new FileObserver(logFile.getAbsolutePath(), FileObserver.MODIFY){
@Override
public void onEvent(int event, String str) {
@ -1089,6 +1077,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
}
};
fobs.startWatching();
*/
new Thread(new Runnable() {
@Override
public void run() {
@ -1271,9 +1260,8 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
((Button) view).setText(isVis ? R.string.control_mouseoff: R.string.control_mouseon);
}
public void dialogForceClose()
{
new AlertDialog.Builder(this)
public static void dialogForceClose(Context ctx) {
new AlertDialog.Builder(ctx)
.setMessage(R.string.mcn_exit_confirm)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
@ -1307,6 +1295,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
@Override
public void onBackPressed() {
// Prevent back
// Catch back as Esc keycode at another place
}
public void hideKeyboard() {

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<TextureView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="@+id/installmod_surfaceview"/>
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="@drawable/mcbutton"
android:layout_alignParentRight="true"
android:text="@string/control_forceclose"
android:onClick="forceClose"/>
</RelativeLayout>

View File

@ -48,7 +48,7 @@
<!-- AlertDialog title -->
<string name="alerttitle_selectkeymap">Pilih sebuah keymap json</string>
<string name="alerttitle_installmod">Pilih sebuah mod untuk di tambah</string>
<string name="alerttitle_installmod">Pilih sebuah mod untuk dipasang</string>
<string name="alerttitle_installoptifine">Pilih jar-nya OptiFine</string>
<!-- Error messages -->

View File

@ -1,9 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="mcl_options">
<item>@string/mcl_option_modmgr</item>
<!-- <item>@string/mcl_option_forgeinstall</item> -->
<item>@string/mcl_option_optifineinstall</item>
<item>@string/mcl_option_modinstall</item>
<item>@string/mcl_option_customcontrol</item>
<item>@string/mcl_option_settings</item>
<item>@string/mcl_option_about</item>

View File

@ -48,8 +48,7 @@
<!-- AlertDialog title -->
<string name="alerttitle_selectkeymap">Select a keymap json</string>
<string name="alerttitle_installmod">Select a mod to add</string>
<string name="alerttitle_installoptifine">Select OptiFine jar file</string>
<string name="alerttitle_installmod">Select a mod to install</string>
<!-- Error messages -->
<string name="error_fatal">PojavLauncher has unexpectedly crashed</string>
@ -87,7 +86,7 @@
<string name="mcl_options">Options</string>
<string name="mcl_option_modmgr">Mod manager (no function)</string>
<string name="mcl_option_optifineinstall">Install OptiFine</string>
<string name="mcl_option_modinstall">Install mod (Forge, LabyMod, Fabric,...)</string>
<string name="mcl_option_checkupdate">Check for update</string>
<string name="mcl_option_customcontrol">Custom controls</string>
<string name="mcl_option_settings">Settings</string>