untrack build artifacts. cleanup unused code

This commit is contained in:
downthecrop 2021-12-11 16:15:06 -08:00
parent bdb7c4fa54
commit e4b26c9a8d
18 changed files with 704 additions and 810 deletions

View file

@ -63,32 +63,13 @@
android:screenOrientation="sensorLandscape"
android:name="net.kdt.pojavlaunch.FatalErrorActivity"
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"/>
<activity
android:theme="@style/MenuDialog"
android:screenOrientation="sensorLandscape"
android:name="net.kdt.pojavlaunch.ExitActivity"
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"/>
<activity
android:screenOrientation="sensorLandscape"
android:name="net.kdt.pojavlaunch.JavaGUILauncherActivity"
android:windowSoftInputMode="adjustPan"
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"/>
<activity
android:screenOrientation="sensorLandscape"
android:name="net.kdt.pojavlaunch.CustomControlsActivity"
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"/>
<activity
android:screenOrientation="sensorLandscape"
android:name="net.kdt.pojavlaunch.authenticator.microsoft.ui.MicrosoftLoginGUIActivity"/>
<activity
android:launchMode="standard"
android:multiprocess="true"
android:screenOrientation="sensorLandscape"
android:name="net.kdt.pojavlaunch.MainActivity"
android:windowSoftInputMode="adjustPan"
android:configChanges="keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|keyboard|navigation"/>
<provider
android:name="net.kdt.pojavlaunch.scoped.GameFolderProvider"
android:authorities="@string/storageProviderAuthorities"

View file

@ -1,10 +1,15 @@
package net.kdt.pojavlaunch;
import android.annotation.SuppressLint;
import android.content.*;
import android.graphics.*;
import android.os.Build;
import android.text.*;
import android.util.*;
import android.view.*;
import androidx.annotation.RequiresApi;
import java.util.*;
import net.kdt.pojavlaunch.utils.*;
import org.lwjgl.glfw.*;
@ -55,7 +60,7 @@ public class AWTCanvasView extends TextureView implements TextureView.SurfaceTex
//Could be optimized
if(forcedScale < 1) { //Auto scale
int minDimension = Math.min(CallbackBridge.physicalHeight, CallbackBridge.physicalWidth);
mScaleFactor = Math.max(((3 * minDimension) / 1080) - 1, 1);
mScaleFactor = 2;
}else{
mScaleFactor = forcedScale;
}
@ -103,22 +108,7 @@ public class AWTCanvasView extends TextureView implements TextureView.SurfaceTex
}
@Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld)
{
System.out.println("WOW THE SIZE CHANGED");
System.out.println(xNew+ " "+yNew);
if(!original){
offsetX = (yNew/8)*-1;
offsetY = xNew/3;
mWidth = offsetX;
mHeight = offsetY;
System.out.println("Placed at "+offsetX+ " "+offsetY);
original = true;
} else{
offsetX = 0;
offsetY = 0;
original = false;
}
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) {
super.onSizeChanged(xNew, yNew, xOld, yOld);
}
@ -154,8 +144,6 @@ public class AWTCanvasView extends TextureView implements TextureView.SurfaceTex
canvas.save();
canvas.scale(mScaleFactor, mScaleFactor);
canvas.translate(-mScales[0],-mScales[1]);
canvas.drawBitmap(rgbArray, 0, CallbackBridge.physicalWidth, offsetX, offsetY, CallbackBridge.physicalWidth, CallbackBridge.physicalHeight, true, null);
canvas.restore();
@ -164,7 +152,6 @@ public class AWTCanvasView extends TextureView implements TextureView.SurfaceTex
// System.gc();
}
canvas.drawText("FPS: " + (Math.round(fps() * 10) / 10) + ", attached=" + attached + ", drawing=" + mDrawing, 50, 50, fpsPaint);
mSurface.unlockCanvasAndPost(canvas);
}
} catch (Throwable th) {

View file

@ -15,9 +15,6 @@ import java.io.*;
import net.kdt.pojavlaunch.multirt.MultiRTConfigDialog;
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
import net.kdt.pojavlaunch.prefs.*;
import net.kdt.pojavlaunch.tasks.*;
import net.kdt.pojavlaunch.value.*;
import org.apache.commons.io.IOUtils;
@ -27,10 +24,7 @@ public abstract class BaseLauncherActivity extends BaseActivity {
public Spinner mVersionSelector;
public MultiRTConfigDialog mRuntimeConfigDialog;
public TextView mLaunchTextStatus;
public JMinecraftVersionList mVersionList;
public MinecraftDownloaderTask mTask;
public MinecraftAccount mProfile;
public String[] mAvailableVersions;
public boolean mIsAssetsProcessing = false;
@ -39,13 +33,6 @@ public abstract class BaseLauncherActivity extends BaseActivity {
public abstract void statusIsLaunching(boolean isLaunching);
/**
* Used by the custom control button from the layout_main_v4
* @param view The view triggering the function
*/
public void launchCustomControlsActivity(View view){
startActivity(new Intent(BaseLauncherActivity.this, CustomControlsActivity.class));
}
/**
* Used by the install button from the layout_main_v4
@ -61,8 +48,8 @@ public abstract class BaseLauncherActivity extends BaseActivity {
statusIsLaunching(false);
} else if (canBack) {
v.setEnabled(false);
mTask = new MinecraftDownloaderTask(this);
mTask.execute(mProfile.selectedVersion);
//mTask = new MinecraftDownloaderTask(this);
//mTask.execute(mProfile.selectedVersion);
}
}
@ -101,12 +88,10 @@ public abstract class BaseLauncherActivity extends BaseActivity {
listRefreshListener = (sharedPreferences, key) -> {
if(key.startsWith("vertype_")) {
System.out.println("Verlist update needed!");
new RefreshVersionListTask(thiz).execute();
}
};
}
LauncherPreferences.DEFAULT_PREF.registerOnSharedPreferenceChangeListener(listRefreshListener);
new RefreshVersionListTask(this).execute();
System.out.println("call to onResumeFragments");
mRuntimeConfigDialog = new MultiRTConfigDialog();
mRuntimeConfigDialog.prepare(this);

View file

@ -21,18 +21,12 @@ import com.kdt.LoggerView;
import java.io.*;
import java.util.*;
import net.kdt.pojavlaunch.customcontrols.*;
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
import net.kdt.pojavlaunch.prefs.*;
import net.kdt.pojavlaunch.utils.*;
import net.kdt.pojavlaunch.value.*;
import org.lwjgl.glfw.*;
public class BaseMainActivity extends BaseActivity {
public static volatile ClipboardManager GLOBAL_CLIPBOARD;
public static TouchCharInput touchCharInput;
volatile public static boolean isInputStackCall;
@ -40,11 +34,7 @@ public class BaseMainActivity extends BaseActivity {
private boolean mIsResuming = false;
private MinecraftGLView minecraftGLView;
private static Touchpad touchpad;
private LoggerView loggerView;
private MinecraftAccount mProfile;
private static Touchpad touchpad; private LoggerView loggerView;
private DrawerLayout drawerLayout;
private NavigationView navDrawer;
@ -52,9 +42,6 @@ public class BaseMainActivity extends BaseActivity {
private NavigationView.OnNavigationItemSelectedListener gameActionListener;
public NavigationView.OnNavigationItemSelectedListener ingameControlsEditorListener;
protected volatile JMinecraftVersionList.Version mVersionInfo;
private PerVersionConfig.VersionConfig config;
protected void initLayout(int resId) {
setContentView(resId);
@ -63,30 +50,9 @@ public class BaseMainActivity extends BaseActivity {
Logger.getInstance().reset();
// FIXME: is it safe fot multi thread?
GLOBAL_CLIPBOARD = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
touchCharInput = findViewById(R.id.mainTouchCharInput);
loggerView = findViewById(R.id.mainLoggerView);
mProfile = PojavProfile.getCurrentProfileContent(this);
mVersionInfo = Tools.getVersionInfo(null,mProfile.selectedVersion);
setTitle("Minecraft " + mProfile.selectedVersion);
PerVersionConfig.update();
config = PerVersionConfig.configMap.get(mProfile.selectedVersion);
String runtime = LauncherPreferences.PREF_DEFAULT_RUNTIME;
if(config != null) {
if(config.selectedRuntime != null) {
if(MultiRTUtils.forceReread(config.selectedRuntime).versionString != null) {
runtime = config.selectedRuntime;
}
}
if(config.renderer != null) {
Tools.LOCAL_RENDERER = config.renderer;
}
}
MultiRTUtils.setRuntimeNamed(this,runtime);
// Minecraft 1.13+
isInputStackCall = mVersionInfo.arguments != null;
Tools.getDisplayMetrics(this);
windowWidth = Tools.getDisplayFriendlyRes(currentDisplayMetrics.widthPixels, scaleFactor);
windowHeight = Tools.getDisplayFriendlyRes(currentDisplayMetrics.heightPixels, scaleFactor);
@ -99,17 +65,22 @@ public class BaseMainActivity extends BaseActivity {
navDrawer = findViewById(R.id.main_navigation_view);
gameActionListener = menuItem -> {
switch (menuItem.getItemId()) {
case R.id.nav_forceclose: dialogForceClose(BaseMainActivity.this);
case R.id.nav_forceclose:
//dialogForceClose(BaseMainActivity.this);
break;
case R.id.nav_viewlog: openLogOutput();
case R.id.nav_viewlog:
//openLogOutput();
break;
case R.id.nav_debug: minecraftGLView.togglepointerDebugging();
//case R.id.nav_debug: minecraftGLView.togglepointerDebugging();
// break;
case R.id.nav_customkey:
//dialogSendCustomKey();
break;
case R.id.nav_customkey: dialogSendCustomKey();
case R.id.nav_mousespd:
//adjustMouseSpeedLive();
break;
case R.id.nav_mousespd: adjustMouseSpeedLive();
break;
case R.id.nav_customctrl: openCustomControls();
case R.id.nav_customctrl:
//openCustomControls();
break;
}
@ -120,22 +91,20 @@ public class BaseMainActivity extends BaseActivity {
touchpad = findViewById(R.id.main_touchpad);
//this.minecraftGLView = findViewById(R.id.main_game_render_view);
//this.drawerLayout.closeDrawers();
this.minecraftGLView = findViewById(R.id.main_game_render_view);
this.drawerLayout.closeDrawers();
minecraftGLView.setSurfaceReadyListener(() -> {
//minecraftGLView.setSurfaceReadyListener(() -> {
try {
runCraft();
//runCraft();
}catch (Throwable e){
Tools.showError(getApplicationContext(), e, true);
}
});
minecraftGLView.start();
//minecraftGLView.start();
} catch(Exception e){
} catch (Throwable e) {
Tools.showError(this, e, true);
}
}
@ -165,34 +134,6 @@ public class BaseMainActivity extends BaseActivity {
return Build.VERSION.SDK_INT >= 26;
}
private void runCraft() throws Throwable {
if(Tools.LOCAL_RENDERER == null) {
Tools.LOCAL_RENDERER = LauncherPreferences.PREF_RENDERER;
}
Logger.getInstance().appendToLog("--------- beggining with launcher debug");
Logger.getInstance().appendToLog("Info: Launcher version: " + BuildConfig.VERSION_NAME);
if (Tools.LOCAL_RENDERER.equals("vulkan_zink")) {
checkVulkanZinkIsSupported();
}
checkLWJGL3Installed();
JREUtils.jreReleaseList = JREUtils.readJREReleaseProperties();
JREUtils.checkJavaArchitecture(this, JREUtils.jreReleaseList.get("OS_ARCH"));
checkJavaArgsIsLaunchable(JREUtils.jreReleaseList.get("JAVA_VERSION"));
// appendlnToLog("Info: Custom Java arguments: \"" + LauncherPreferences.PREF_CUSTOM_JAVA_ARGS + "\"");
Logger.getInstance().appendToLog("Info: Selected Minecraft version: " + mVersionInfo.id +
((mVersionInfo.inheritsFrom == null || mVersionInfo.inheritsFrom.equals(mVersionInfo.id)) ?
"" : " (" + mVersionInfo.inheritsFrom + ")"));
JREUtils.redirectAndPrintJRELog(this);
Tools.launchMinecraft(this, mProfile, mProfile.selectedVersion);
}
private void checkJavaArgsIsLaunchable(String jreVersion) throws Throwable {
Logger.getInstance().appendToLog("Info: Custom Java arguments: \"" + LauncherPreferences.PREF_CUSTOM_JAVA_ARGS + "\"");
}
private void checkLWJGL3Installed() {
File lwjgl3dir = new File(Tools.DIR_GAME_HOME, "lwjgl3");
if (!lwjgl3dir.exists() || lwjgl3dir.isFile() || lwjgl3dir.list().length == 0) {
@ -233,42 +174,8 @@ public class BaseMainActivity extends BaseActivity {
return s.toString();
}
private void dialogSendCustomKey() {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle(R.string.control_customkey);
dialog.setItems(EfficientAndroidLWJGLKeycode.generateKeyName(), (dInterface, position) -> EfficientAndroidLWJGLKeycode.execKeyIndex(position));
dialog.show();
}
boolean isInEditor;
private void openCustomControls() {
if(ingameControlsEditorListener == null) return;
((MainActivity)this).mControlLayout.setModifiable(true);
navDrawer.getMenu().clear();
navDrawer.inflateMenu(R.menu.menu_customctrl);
navDrawer.setNavigationItemSelectedListener(ingameControlsEditorListener);
isInEditor = true;
}
public void leaveCustomControls() {
if(this instanceof MainActivity) {
try {
MainActivity.mControlLayout.hideAllHandleViews();
MainActivity.mControlLayout.loadLayout((CustomControls)null);
MainActivity.mControlLayout.setModifiable(false);
System.gc();
MainActivity.mControlLayout.loadLayout(LauncherPreferences.DEFAULT_PREF.getString("defaultCtrl",Tools.CTRLDEF_FILE));
} catch (IOException e) {
Tools.showError(this,e);
}
//((MainActivity) this).mControlLayout.loadLayout((CustomControls)null);
}
navDrawer.getMenu().clear();
navDrawer.inflateMenu(R.menu.menu_runopt);
navDrawer.setNavigationItemSelectedListener(gameActionListener);
isInEditor = false;
}
private void openLogOutput() {
loggerView.setVisibility(View.VISIBLE);
mIsResuming = false;
@ -304,20 +211,6 @@ public class BaseMainActivity extends BaseActivity {
}).show();
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && !touchCharInput.isEnabled()) {
if(event.getAction() != KeyEvent.ACTION_UP) return true; // We eat it anyway
sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_ESCAPE);
return true;
}
return super.dispatchKeyEvent(event);
}
public static void switchKeyboardState() {
if(touchCharInput != null) touchCharInput.switchKeyboardState();
}
int tmpMouseSpeed;
public void adjustMouseSpeedLive() {

View file

@ -29,7 +29,6 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
String specialChars = "/*!@#$%^&*()\"{}_[+=-_]\'|\\?/<>,.";
private LoggerView loggerView;
private boolean mouseState = false;
private int mode = 0;
private LinearLayout touchPad;
private ImageView mousePointer;
@ -72,24 +71,11 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
@Override
public boolean onScale(ScaleGestureDetector detector) {
float scaleFactor = detector.getScaleFactor();
switch(mode){
case 0: // Pinch to Zoom
if (scaleFactor > 1) {
//Send F4 To Zoom Out
AWTInputBridge.sendKey((char)115,115);
} else {
//116
AWTInputBridge.sendKey((char)116,116);
}
break;
case 1: // Right click
AWTInputBridge.sendKey((char)122,122);
AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK);
break;
if (scaleFactor > 1) { //Send F4 To Zoom Out
AWTInputBridge.sendKey((char)115,115);
} else { //116 F5 To Zoom In
AWTInputBridge.sendKey((char) 116, 116);
}
return true;
}
@ -108,13 +94,11 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
@Override
public boolean onDown(MotionEvent event) {
//...
return super.onDown(event);
}
@Override
public boolean onSingleTapUp(MotionEvent event) {
//...
return true;
}
@ -149,7 +133,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
this.touchPad = findViewById(R.id.main_touchpad);
touchPad.setFocusable(false);
touchPad.setVisibility(View.GONE);
touchPad.setVisibility(View.VISIBLE);
this.mousePointer = findViewById(R.id.main_mouse_pointer);
this.mousePointer.post(() -> {
@ -162,17 +146,6 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
private float prevX, prevY;
@Override
public boolean onTouch(View v, MotionEvent event) {
mode = 1;
//longTapGestureDetector.onLongPress(event);
// MotionEvent reports input details from the touch screen
// and other input controls. In this case, you are only
// interested in events where the touch position changed.
// int index = event.getActionIndex();
//System.out.println("sending pos: "+prevX+","+prevY);
//sendScaledMousePosition(prevX,prevY);
//AWTInputBridge.sendMousePress(AWTInputEvent.NOBUTTON);
int action = event.getActionMasked();
float x = event.getX();
@ -192,6 +165,9 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
clearRC();
} else {
switch (action) {
case MotionEvent.ACTION_POINTER_DOWN: //Second finger rightclicking
AWTInputBridge.sendKey((char)122,122);
AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK);
case MotionEvent.ACTION_UP: // 1
case MotionEvent.ACTION_CANCEL: // 3
case MotionEvent.ACTION_POINTER_UP: // 6
@ -212,8 +188,6 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
}
}
scaleGestureDetector.onTouchEvent(event);
// debugText.setText(CallbackBridge.DEBUG_STRING.toString());
CallbackBridge.DEBUG_STRING.setLength(0);
@ -226,15 +200,12 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
// this.textLogBehindGL = (TextView) findViewById(R.id.main_log_behind_GL);
// this.textLogBehindGL.setTypeface(Typeface.MONOSPACE);
final File modFile = (File) getIntent().getExtras().getSerializable("modFile");
final String javaArgs = getIntent().getExtras().getString("javaArgs");
mTextureView = findViewById(R.id.installmod_surfaceview);
mTextureView.setOnTouchListener((v, event) -> {
mode = 0;
if(scaleGestureDetector.onTouchEvent(event)){
}
scaleGestureDetector.onTouchEvent(event);
float x = event.getX();
float y = event.getY();
if (gestureDetector.onTouchEvent(event)) {
@ -242,7 +213,6 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK);
return true;
}
switch (event.getActionMasked()) {
case MotionEvent.ACTION_UP: // 1
case MotionEvent.ACTION_CANCEL: // 3
@ -266,12 +236,6 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
try {
final int exit = doCustomInstall(modFile, javaArgs);
Logger.getInstance().appendToLog(getString(R.string.toast_optifine_success));
if (exit != 0) return;
runOnUiThread(() -> {
Toast.makeText(JavaGUILauncherActivity.this, R.string.toast_optifine_success, Toast.LENGTH_SHORT).show();
MainActivity.fullyExit();
});
} catch (Throwable e) {
Logger.getInstance().appendToLog("Install failed:");
Logger.getInstance().appendToLog(Log.getStackTraceString(e));
@ -284,18 +248,6 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
//scaleUp(mTextureView);
}
private void clearRC(){
rcState = false;
AWTInputBridge.sendKey((char)121,121);
findViewById(R.id.installmod_mouse_sec).setBackground(getResources().getDrawable( R.drawable.control_button ));
}
private void activateRC(){
rcState = true;
AWTInputBridge.sendKey((char)122,122);
findViewById(R.id.installmod_mouse_sec).setBackground(getResources().getDrawable( R.drawable.control_button_pressed ));
}
@Override
public boolean onTouch(View v, MotionEvent e) {
long time = System.currentTimeMillis();
@ -337,10 +289,11 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getAction() == KeyEvent.ACTION_DOWN){
//Log.i("key getKeycode", String.valueOf(event.getKeyCode()));
//Log.i("key unicode", String.valueOf((char)event.getUnicodeChar()));
//Log.i("key unicode int", String.valueOf(event.getUnicodeChar()));
/*
Log.i("key getKeycode", String.valueOf(event.getKeyCode()));
Log.i("key unicode", String.valueOf((char)event.getUnicodeChar()));
Log.i("key unicode int", String.valueOf(event.getUnicodeChar()));
*/
if(event.getKeyCode() == 67){
// Backspace
AWTInputBridge.sendKey((char)0x08,0x08);
@ -409,7 +362,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
c = '\\';
break;
}
System.out.println("I SEE A "+(char)event.getUnicodeChar());
//System.out.println("I SEE A "+(char)event.getUnicodeChar());
if(c != (char)event.getUnicodeChar()){
System.out.println("REPLACED with "+(char)c);
AWTInputBridge.sendKey((char)123,123);
@ -436,6 +389,18 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
return true;
}
private void clearRC(){
rcState = false;
AWTInputBridge.sendKey((char)121,121);
findViewById(R.id.installmod_mouse_sec).setBackground(getResources().getDrawable( R.drawable.control_button ));
}
private void activateRC(){
rcState = true;
AWTInputBridge.sendKey((char)122,122);
findViewById(R.id.installmod_mouse_sec).setBackground(getResources().getDrawable( R.drawable.control_button_pressed ));
}
public void placeMouseAdd(float x, float y) {
this.mousePointer.setX(mousePointer.getX() + x);
this.mousePointer.setY(mousePointer.getY() + y);
@ -469,9 +434,9 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTou
public void toggleVirtualMouse(View v) {
isVirtualMouseEnabled = !isVirtualMouseEnabled;
touchPad.setVisibility(isVirtualMouseEnabled ? View.VISIBLE : View.GONE);
touchPad.setVisibility(isVirtualMouseEnabled ? View.GONE : View.VISIBLE);
Toast.makeText(this,
isVirtualMouseEnabled ? R.string.control_mouseon : R.string.control_mouseoff,
isVirtualMouseEnabled ? R.string.control_mouseoff : R.string.control_mouseon,
Toast.LENGTH_SHORT).show();
}

View file

@ -0,0 +1,91 @@
package net.kdt.pojavlaunch;
import android.app.*;
import android.content.*;
import android.content.pm.*;
import android.content.res.*;
import android.os.*;
import androidx.core.app.*;
import android.util.*;
import java.io.*;
import java.text.*;
import java.util.*;
import net.kdt.pojavlaunch.utils.*;
public class PojavApplication extends Application
{
public static String CRASH_REPORT_TAG = "PojavCrashReport";
@Override
public void onCreate() {
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
@Override
public void uncaughtException(Thread thread, Throwable th) {
boolean storagePermAllowed = Build.VERSION.SDK_INT < 23 || ActivityCompat.checkSelfPermission(PojavApplication.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
File crashFile = new File(storagePermAllowed ? Tools.DIR_GAME_HOME : Tools.DIR_DATA, "latestcrash.txt");
try {
// Write to file, since some devices may not able to show error
crashFile.getParentFile().mkdirs();
crashFile.createNewFile();
PrintStream crashStream = new PrintStream(crashFile);
crashStream.append("PojavLauncher crash report\n");
crashStream.append(" - Time: " + DateFormat.getDateTimeInstance().format(new Date()) + "\n");
crashStream.append(" - Device: " + Build.PRODUCT + " " + Build.MODEL + "\n");
crashStream.append(" - Android version: " + Build.VERSION.RELEASE + "\n");
crashStream.append(" - Crash stack trace:\n");
crashStream.append(" - Launcher version: " + BuildConfig.VERSION_NAME + "\n");
crashStream.append(Log.getStackTraceString(th));
crashStream.close();
} catch (Throwable th2) {
Log.e(CRASH_REPORT_TAG, " - Exception attempt saving crash stack trace:", th2);
Log.e(CRASH_REPORT_TAG, " - The crash stack trace was:", th);
}
FatalErrorActivity.showError(PojavApplication.this, crashFile.getAbsolutePath(), storagePermAllowed, th);
// android.os.Process.killProcess(android.os.Process.myPid());
BaseMainActivity.fullyExit();
}
});
try {
super.onCreate();
Tools.APP_NAME = getResources().getString(R.string.app_short_name);
Tools.DIR_DATA = getDir("files", MODE_PRIVATE).getParent();
//Tools.DIR_HOME_JRE = Tools.DIR_DATA + "/jre_runtime".replace("/data/user/0", "/data/data");
Tools.DIR_ACCOUNT_OLD = Tools.DIR_DATA + "/Users";
Tools.DIR_ACCOUNT_NEW = Tools.DIR_DATA + "/accounts";
// Tools.FILE_ACCOUNT_JSON = getFilesDir().getAbsolutePath() + "/account_profiles.json";
Tools.DEVICE_ARCHITECTURE = Architecture.getDeviceArchitecture();
//Force x86 lib directory for Asus x86 based zenfones
if(Architecture.isx86Device() && Architecture.is32BitsDevice()){
String originalJNIDirectory = getApplicationInfo().nativeLibraryDir;
getApplicationInfo().nativeLibraryDir = originalJNIDirectory.substring(0,
originalJNIDirectory.lastIndexOf("/"))
.concat("/x86");
}
} catch (Throwable th) {
Intent ferrorIntent = new Intent(this, FatalErrorActivity.class);
ferrorIntent.putExtra("throwable", th);
startActivity(ferrorIntent);
}
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleUtils.setLocale(base));
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
LocaleUtils.setLocale(this);
}
}

View file

@ -5,14 +5,11 @@ import static net.kdt.pojavlaunch.Tools.getFileName;
import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@ -21,8 +18,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
@ -35,17 +30,9 @@ import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import net.kdt.pojavlaunch.authenticator.microsoft.MicrosoftAuthTask;
import net.kdt.pojavlaunch.authenticator.microsoft.ui.MicrosoftLoginGUIActivity;
import net.kdt.pojavlaunch.authenticator.mojang.InvalidateTokenTask;
import net.kdt.pojavlaunch.authenticator.mojang.LoginListener;
import net.kdt.pojavlaunch.authenticator.mojang.LoginTask;
import net.kdt.pojavlaunch.authenticator.mojang.RefreshListener;
import net.kdt.pojavlaunch.customcontrols.CustomControls;
import net.kdt.pojavlaunch.multirt.MultiRTConfigDialog;
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
import net.kdt.pojavlaunch.value.MinecraftAccount;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
@ -68,7 +55,6 @@ public class PojavLoginActivity extends BaseActivity
private CheckBox sRemember, sOffline;
private TextView startupTextView;
private SharedPreferences firstLaunchPrefs;
private MinecraftAccount mProfile = null;
private boolean isSkipInit = false;
private boolean isStarting = false;
@ -202,9 +188,7 @@ public class PojavLoginActivity extends BaseActivity
super.onResume();
Tools.updateWindowSize(this);
// Clear current profile
PojavProfile.setCurrentProfile(this, null);
}
@ -259,22 +243,14 @@ public class PojavLoginActivity extends BaseActivity
}
private void initMain() throws Throwable {
mkdirs(Tools.DIR_ACCOUNT_NEW);
PojavMigrator.migrateAccountData(this);
mkdirs(Tools.DIR_GAME_HOME);
mkdirs(Tools.DIR_GAME_HOME + "/lwjgl3");
mkdirs(Tools.DIR_GAME_HOME + "/config");
if (!PojavMigrator.migrateGameDir()) {
mkdirs(Tools.DIR_GAME_NEW);
mkdirs(Tools.DIR_GAME_NEW + "/mods");
mkdirs(Tools.DIR_HOME_VERSION);
mkdirs(Tools.DIR_HOME_LIBRARY);
}
mkdirs(Tools.CTRLMAP_PATH);
try {
new CustomControls(this).save(Tools.CTRLDEF_FILE);
Tools.copyAssetFile(this, "components/security/pro-grade.jar", Tools.DIR_DATA, true);
Tools.copyAssetFile(this, "components/security/java_sandbox.policy", Tools.DIR_DATA, true);
@ -323,9 +299,6 @@ public class PojavLoginActivity extends BaseActivity
});
t.start();
}
}else if(requestCode == MicrosoftLoginGUIActivity.AUTHENTICATE_MICROSOFT_REQUEST) {
//Log.i("MicroLoginWrap","Got microsoft login result:" + data);
performMicroLogin(data);
}
}
}
@ -362,12 +335,7 @@ public class PojavLoginActivity extends BaseActivity
else return file.mkdirs();
}
public void loginMicrosoft(View view) {
Intent i = new Intent(this,MicrosoftLoginGUIActivity.class);
startActivityForResult(i,MicrosoftLoginGUIActivity.AUTHENTICATE_MICROSOFT_REQUEST);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
@ -383,21 +351,6 @@ public class PojavLoginActivity extends BaseActivity
if (!error_description.startsWith("The user has denied access to the scope requested by the client application")) {
Toast.makeText(this, "Error: " + error + ": " + error_description, Toast.LENGTH_LONG).show();
}
} else {
String code = data.getQueryParameter("code");
new MicrosoftAuthTask(this, new RefreshListener(){
@Override
public void onFailed(Throwable e) {
Tools.showError(PojavLoginActivity.this, e);
}
@Override
public void onSuccess(MinecraftAccount b) {
mProfile = b;
playProfile(false);
}
}).execute("false", code);
// Toast.makeText(this, "Logged in to Microsoft account, but NYI", Toast.LENGTH_LONG).show();
}
}
}
@ -412,187 +365,19 @@ public class PojavLoginActivity extends BaseActivity
return listView.getChildAt(childIndex);
}
}
public void loginSavedAcc(View view) {
String[] accountArr = new File(Tools.DIR_ACCOUNT_NEW).list();
if(accountArr.length == 0){
showNoAccountDialog();
return;
}
final Dialog accountDialog = new Dialog(PojavLoginActivity.this);
accountDialog.setContentView(R.layout.simple_account_list_holder);
LinearLayout accountListLayout = accountDialog.findViewById(R.id.accountListLayout);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
for (int accountIndex = 0; accountIndex < accountArr.length; accountIndex++) {
String s = accountArr[accountIndex];
View child = inflater.inflate(R.layout.simple_account_list_item, accountListLayout,false);
TextView accountName = child.findViewById(R.id.accountitem_text_name);
ImageButton removeButton = child.findViewById(R.id.accountitem_button_remove);
ImageView imageView = child.findViewById(R.id.account_head);
String accNameStr = s.substring(0, s.length() - 5);
imageView.setImageBitmap(MinecraftAccount.load(accNameStr).getSkinFace());
accountName.setText(accNameStr);
accountListLayout.addView(child);
accountName.setOnClickListener(new View.OnClickListener() {
final String selectedAccName = accountName.getText().toString();
@Override
public void onClick(View v) {
try {
RefreshListener authListener = new RefreshListener(){
@Override
public void onFailed(Throwable e) {
Tools.showError(PojavLoginActivity.this, e);
}
@Override
public void onSuccess(MinecraftAccount out) {
accountDialog.dismiss();
mProfile = out;
playProfile(true);
}
};
MinecraftAccount acc = MinecraftAccount.load(selectedAccName);
if (acc.isMicrosoft){
new MicrosoftAuthTask(PojavLoginActivity.this, authListener)
.execute("true", acc.msaRefreshToken);
} else if (acc.accessToken.length() >= 5) {
PojavProfile.updateTokens(PojavLoginActivity.this, selectedAccName, authListener);
} else {
accountDialog.dismiss();
PojavProfile.launch(PojavLoginActivity.this, selectedAccName);
}
} catch (Exception e) {
Tools.showError(PojavLoginActivity.this, e);
}
}
});
final int accountIndex_final = accountIndex;
removeButton.setOnClickListener(new View.OnClickListener() {
final String selectedAccName = accountName.getText().toString();
@Override
public void onClick(View v) {
AlertDialog.Builder builder2 = new AlertDialog.Builder(PojavLoginActivity.this);
builder2.setTitle(selectedAccName);
builder2.setMessage(R.string.warning_remove_account);
builder2.setPositiveButton(android.R.string.ok, (p1, p2) -> {
new InvalidateTokenTask(PojavLoginActivity.this).execute(selectedAccName);
accountListLayout.removeViewsInLayout(accountIndex_final, 1);
if (accountListLayout.getChildCount() == 0) {
accountDialog.dismiss(); //No need to keep it, since there is no account
return;
}
//Refreshes the layout with the same settings so it take the missing child into account.
accountListLayout.setLayoutParams(accountListLayout.getLayoutParams());
});
builder2.setNegativeButton(android.R.string.cancel, null);
builder2.show();
}
});
}
accountDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
accountDialog.show();
}
private MinecraftAccount loginOffline() {
new File(Tools.DIR_ACCOUNT_OLD).mkdir();
String text = edit2.getText().toString();
if (text.isEmpty()) {
edit2.setError(getString(R.string.global_error_field_empty));
} else if (text.length() < 3 || text.length() > 16 || !text.matches("\\w+")) {
edit2.setError(getString(R.string.login_error_invalid_username));
} else if (new File(Tools.DIR_ACCOUNT_NEW + "/" + text + ".json").exists()) {
edit2.setError(getString(R.string.login_error_exist_username));
} else if (!edit3.getText().toString().isEmpty()) {
edit3.setError(getString(R.string.login_error_offline_password));
} else {
MinecraftAccount builder = new MinecraftAccount();
builder.isMicrosoft = false;
builder.username = text;
return builder;
}
return null;
}
public void loginMC(final View v)
{
if (sOffline.isChecked()) {
mProfile = loginOffline();
playProfile(false);
} else {
ProgressBar prb = findViewById(R.id.launcherAccProgress);
new LoginTask().setLoginListener(new LoginListener(){
@Override
public void onBeforeLogin() {
v.setEnabled(false);
prb.setVisibility(View.VISIBLE);
}
@Override
public void onLoginDone(String[] result) {
if(result[0].equals("ERROR")){
Tools.dialogOnUiThread(PojavLoginActivity.this,
getResources().getString(R.string.global_error), strArrToString(result));
} else{
MinecraftAccount builder = new MinecraftAccount();
builder.accessToken = result[1];
builder.clientToken = result[2];
builder.profileId = result[3];
builder.username = result[4];
builder.updateSkinFace();
mProfile = builder;
}
runOnUiThread(() -> {
v.setEnabled(true);
prb.setVisibility(View.GONE);
playProfile(false);
});
}
}).execute(edit2.getText().toString(), edit3.getText().toString());
}
}
private void playProfile(boolean notOnLogin) {
if (mProfile != null) {
try {
String profileName = null;
if (sRemember.isChecked() || notOnLogin) {
profileName = mProfile.save();
}
PojavProfile.launch(PojavLoginActivity.this, profileName == null ? mProfile : profileName);
} catch (IOException e) {
Tools.showError(this, e);
}
}
}
public static String strArrToString(String[] strArr)
{
String[] strArrEdit = strArr.clone();
strArrEdit[0] = "";
String str = Arrays.toString(strArrEdit);
str = str.substring(1, str.length() - 1).replace(",", "\n");
return str;
}
//We are calling this method to check the permission status

View file

@ -10,15 +10,12 @@ import android.util.*;
import com.google.gson.*;
import java.io.*;
import java.lang.reflect.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.*;
import java.util.*;
import java.util.zip.*;
import net.kdt.pojavlaunch.prefs.*;
import net.kdt.pojavlaunch.utils.*;
import net.kdt.pojavlaunch.value.*;
import org.apache.commons.codec.binary.Hex;
import org.lwjgl.glfw.*;
@ -89,68 +86,6 @@ public final class Tools {
CTRLMAP_PATH = DIR_GAME_HOME + "/controlmap";
CTRLDEF_FILE = DIR_GAME_HOME + "/controlmap/default.json";
}
public static void launchMinecraft(final Activity activity, MinecraftAccount profile, String versionName) throws Throwable {
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
((ActivityManager)activity.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryInfo(mi);
if(LauncherPreferences.PREF_RAM_ALLOCATION > (mi.availMem/1048576L)) {
Object memoryErrorLock = new Object();
activity.runOnUiThread(() -> {
androidx.appcompat.app.AlertDialog.Builder b = new androidx.appcompat.app.AlertDialog.Builder(activity)
.setMessage(activity.getString(R.string.memory_warning_msg,(mi.availMem/1048576L),LauncherPreferences.PREF_RAM_ALLOCATION))
.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {synchronized(memoryErrorLock){memoryErrorLock.notifyAll();}})
.setOnCancelListener((i) -> {synchronized(memoryErrorLock){memoryErrorLock.notifyAll();}});
b.show();
});
synchronized (memoryErrorLock) {
memoryErrorLock.wait();
}
}
JMinecraftVersionList.Version versionInfo = Tools.getVersionInfo(null,versionName);
PerVersionConfig.update();
PerVersionConfig.VersionConfig pvcConfig = PerVersionConfig.configMap.get(versionName);
String gamedirPath;
if(pvcConfig != null && pvcConfig.gamePath != null && !pvcConfig.gamePath.isEmpty()) gamedirPath = pvcConfig.gamePath;
else gamedirPath = Tools.DIR_GAME_NEW;
if(pvcConfig != null && pvcConfig.jvmArgs != null && !pvcConfig.jvmArgs.isEmpty()) LauncherPreferences.PREF_CUSTOM_JAVA_ARGS = pvcConfig.jvmArgs;
PojavLoginActivity.disableSplash(gamedirPath);
String[] launchArgs = getMinecraftArgs(profile, versionInfo, gamedirPath);
// ctx.appendlnToLog("Minecraft Args: " + Arrays.toString(launchArgs));
String launchClassPath = generateLaunchClassPath(versionInfo,versionName);
List<String> javaArgList = new ArrayList<String>();
// Only Java 8 supports headful AWT for now
if (JREUtils.jreReleaseList.get("JAVA_VERSION").equals("1.8.0")) {
getCacioJavaArgs(javaArgList, false);
}
/*
int mcReleaseDate = Integer.parseInt(versionInfo.releaseTime.substring(0, 10).replace("-", ""));
// 13w17a: 20130425
// 13w18a: 20130502
if (mcReleaseDate < 20130502 && versionInfo.minimumLauncherVersion < 9){
ctx.appendlnToLog("AWT-enabled version detected! ("+mcReleaseDate+")");
getCacioJavaArgs(javaArgList,false);
}else{
getCacioJavaArgs(javaArgList,false); // true
ctx.appendlnToLog("Headless version detected! ("+mcReleaseDate+")");
}
*/
javaArgList.add("-cp");
javaArgList.add(getLWJGL3ClassPath() + ":" + launchClassPath);
javaArgList.add(versionInfo.mainClass);
javaArgList.addAll(Arrays.asList(launchArgs));
// ctx.appendlnToLog("full args: "+javaArgList.toString());
JREUtils.launchJavaVM(activity, javaArgList);
}
public static void getCacioJavaArgs(List<String> javaArgList, boolean isHeadless) {
javaArgList.add("-Djava.awt.headless="+isHeadless);
@ -176,74 +111,6 @@ public final class Tools {
javaArgList.add(cacioClasspath.toString());
}
public static String[] getMinecraftArgs(MinecraftAccount profile, JMinecraftVersionList.Version versionInfo, String strGameDir) {
String username = profile.username;
String versionName = versionInfo.id;
if (versionInfo.inheritsFrom != null) {
versionName = versionInfo.inheritsFrom;
}
String userType = "mojang";
File gameDir = new File(strGameDir);
gameDir.mkdirs();
Map<String, String> varArgMap = new ArrayMap<>();
varArgMap.put("auth_access_token", profile.accessToken);
varArgMap.put("auth_player_name", username);
varArgMap.put("auth_uuid", profile.profileId);
varArgMap.put("assets_root", Tools.ASSETS_PATH);
varArgMap.put("assets_index_name", versionInfo.assets);
varArgMap.put("game_assets", Tools.ASSETS_PATH);
varArgMap.put("game_directory", gameDir.getAbsolutePath());
varArgMap.put("user_properties", "{}");
varArgMap.put("user_type", userType);
varArgMap.put("version_name", versionName);
varArgMap.put("version_type", versionInfo.type);
List<String> minecraftArgs = new ArrayList<String>();
if (versionInfo.arguments != null) {
// Support Minecraft 1.13+
for (Object arg : versionInfo.arguments.game) {
if (arg instanceof String) {
minecraftArgs.add((String) arg);
} else {
/*
JMinecraftVersionList.Arguments.ArgValue argv = (JMinecraftVersionList.Arguments.ArgValue) arg;
if (argv.values != null) {
minecraftArgs.add(argv.values[0]);
} else {
for (JMinecraftVersionList.Arguments.ArgValue.ArgRules rule : arg.rules) {
// rule.action = allow
// TODO implement this
}
}
*/
}
}
}
minecraftArgs.add("--width");
minecraftArgs.add(Integer.toString(CallbackBridge.windowWidth));
minecraftArgs.add("--height");
minecraftArgs.add(Integer.toString(CallbackBridge.windowHeight));
minecraftArgs.add("--fullscreenWidth");
minecraftArgs.add(Integer.toString(CallbackBridge.windowWidth));
minecraftArgs.add("--fullscreenHeight");
minecraftArgs.add(Integer.toString(CallbackBridge.windowHeight));
String[] argsFromJson = JSONUtils.insertJSONValueList(
splitAndFilterEmpty(
versionInfo.minecraftArguments == null ?
fromStringArray(minecraftArgs.toArray(new String[0])):
versionInfo.minecraftArguments
), varArgMap
);
// Tools.dialogOnUiThread(this, "Result args", Arrays.asList(argsFromJson).toString());
return argsFromJson;
}
public static String fromStringArray(String[] strArr) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < strArr.length; i++) {
@ -289,47 +156,6 @@ public final class Tools {
}
private static boolean isClientFirst = false;
public static String generateLaunchClassPath(JMinecraftVersionList.Version info,String actualname) {
StringBuilder libStr = new StringBuilder(); //versnDir + "/" + version + "/" + version + ".jar:";
String[] classpath = generateLibClasspath(info);
// Debug: LWJGL 3 override
// File lwjgl2Folder = new File(Tools.MAIN_PATH, "lwjgl2");
/*
File lwjgl3Folder = new File(Tools.MAIN_PATH, "lwjgl3");
if (lwjgl3Folder.exists()) {
for (File file: lwjgl3Folder.listFiles()) {
if (file.getName().endsWith(".jar")) {
libStr.append(file.getAbsolutePath() + ":");
}
}
} else if (lwjgl2Folder.exists()) {
for (File file: lwjgl2Folder.listFiles()) {
if (file.getName().endsWith(".jar")) {
libStr.append(file.getAbsolutePath() + ":");
}
}
}
*/
if (isClientFirst) {
libStr.append(getPatchedFile(actualname));
}
for (String perJar : classpath) {
if (!new File(perJar).exists()) {
Log.d(APP_NAME, "Ignored non-exists file: " + perJar);
continue;
}
libStr.append((isClientFirst ? ":" : "") + perJar + (!isClientFirst ? ":" : ""));
}
if (!isClientFirst) {
libStr.append(getPatchedFile(actualname));
}
return libStr.toString();
}
public static DisplayMetrics getDisplayMetrics(Activity activity) {
DisplayMetrics displayMetrics = new DisplayMetrics();
@ -505,131 +331,6 @@ public final class Tools {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
act.startActivity(browserIntent);
}
public static String[] generateLibClasspath(JMinecraftVersionList.Version info) {
List<String> libDir = new ArrayList<String>();
for (DependentLibrary libItem: info.libraries) {
String[] libInfos = libItem.name.split(":");
libDir.add(Tools.DIR_HOME_LIBRARY + "/" + Tools.artifactToPath(libInfos[0], libInfos[1], libInfos[2]));
}
return libDir.toArray(new String[0]);
}
public static JMinecraftVersionList.Version getVersionInfo(BaseLauncherActivity bla, String versionName) {
try {
JMinecraftVersionList.Version customVer = Tools.GLOBAL_GSON.fromJson(read(DIR_HOME_VERSION + "/" + versionName + "/" + versionName + ".json"), JMinecraftVersionList.Version.class);
for (DependentLibrary lib : customVer.libraries) {
if (lib.name.startsWith(LIBNAME_OPTIFINE)) {
customVer.optifineLib = lib;
}
}
if (customVer.inheritsFrom == null || customVer.inheritsFrom.equals(customVer.id)) {
return customVer;
} else {
JMinecraftVersionList.Version inheritsVer = null;
if(bla != null) if (bla.mVersionList != null) {
for (JMinecraftVersionList.Version valueVer : bla.mVersionList.versions) {
if (valueVer.id.equals(customVer.inheritsFrom) && (!new File(DIR_HOME_VERSION + "/" + customVer.inheritsFrom + "/" + customVer.inheritsFrom + ".json").exists()) && (valueVer.url != null)) {
Tools.downloadFile(valueVer.url,DIR_HOME_VERSION + "/" + customVer.inheritsFrom + "/" + customVer.inheritsFrom + ".json");
}
}
}//If it won't download, just search for it
try{
inheritsVer = Tools.GLOBAL_GSON.fromJson(read(DIR_HOME_VERSION + "/" + customVer.inheritsFrom + "/" + customVer.inheritsFrom + ".json"), JMinecraftVersionList.Version.class);
}catch(IOException e) {
throw new RuntimeException("Can't find the source version for "+ versionName +" (req version="+customVer.inheritsFrom+")");
}
inheritsVer.inheritsFrom = inheritsVer.id;
insertSafety(inheritsVer, customVer,
"assetIndex", "assets", "id",
"mainClass", "minecraftArguments",
"optifineLib", "releaseTime", "time", "type"
);
List<DependentLibrary> libList = new ArrayList<DependentLibrary>(Arrays.asList(inheritsVer.libraries));
try {
loop_1:
for (DependentLibrary lib : customVer.libraries) {
String libName = lib.name.substring(0, lib.name.lastIndexOf(":"));
for (int i = 0; i < libList.size(); i++) {
DependentLibrary libAdded = libList.get(i);
String libAddedName = libAdded.name.substring(0, libAdded.name.lastIndexOf(":"));
if (libAddedName.equals(libName)) {
Log.d(APP_NAME, "Library " + libName + ": Replaced version " +
libName.substring(libName.lastIndexOf(":") + 1) + " with " +
libAddedName.substring(libAddedName.lastIndexOf(":") + 1));
libList.set(i, lib);
continue loop_1;
}
}
libList.add(lib);
}
} finally {
inheritsVer.libraries = libList.toArray(new DependentLibrary[0]);
}
// Inheriting Minecraft 1.13+ with append custom args
if (inheritsVer.arguments != null && customVer.arguments != null) {
List totalArgList = new ArrayList();
totalArgList.addAll(Arrays.asList(inheritsVer.arguments.game));
int nskip = 0;
for (int i = 0; i < customVer.arguments.game.length; i++) {
if (nskip > 0) {
nskip--;
continue;
}
Object perCustomArg = customVer.arguments.game[i];
if (perCustomArg instanceof String) {
String perCustomArgStr = (String) perCustomArg;
// Check if there is a duplicate argument on combine
if (perCustomArgStr.startsWith("--") && totalArgList.contains(perCustomArgStr)) {
perCustomArg = customVer.arguments.game[i + 1];
if (perCustomArg instanceof String) {
perCustomArgStr = (String) perCustomArg;
// If the next is argument value, skip it
if (!perCustomArgStr.startsWith("--")) {
nskip++;
}
}
} else {
totalArgList.add(perCustomArgStr);
}
} else if (!totalArgList.contains(perCustomArg)) {
totalArgList.add(perCustomArg);
}
}
inheritsVer.arguments.game = totalArgList.toArray(new Object[0]);
}
return inheritsVer;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// Prevent NullPointerException
private static void insertSafety(JMinecraftVersionList.Version targetVer, JMinecraftVersionList.Version fromVer, String... keyArr) {
for (String key : keyArr) {
Object value = null;
try {
Field fieldA = fromVer.getClass().getDeclaredField(key);
value = fieldA.get(fromVer);
if (((value instanceof String) && !((String) value).isEmpty()) || value != null) {
Field fieldB = targetVer.getClass().getDeclaredField(key);
fieldB.set(targetVer, value);
}
} catch (Throwable th) {
Log.w(Tools.APP_NAME, "Unable to insert " + key + "=" + value, th);
}
}
}
public static String convertStream(InputStream inputStream) throws IOException {
return convertStream(inputStream, Charset.forName("UTF-8"));
@ -717,29 +418,6 @@ public final class Tools {
File file = new File(nameOutput);
DownloadUtils.downloadFile(urlInput, file);
}
public abstract static class DownloaderFeedback {
public abstract void updateProgress(int curr, int max);
}
public static void downloadFileMonitored(String urlInput,String nameOutput, DownloaderFeedback monitor) throws IOException {
File nameOutputFile = new File(nameOutput);
if (!nameOutputFile.exists()) {
nameOutputFile.getParentFile().mkdirs();
}
HttpURLConnection conn = (HttpURLConnection) new URL(urlInput).openConnection();
InputStream readStr = conn.getInputStream();
FileOutputStream fos = new FileOutputStream(nameOutputFile);
int cur = 0;
int oval = 0;
int len = conn.getContentLength();
byte[] buf = new byte[65535];
while ((cur = readStr.read(buf)) != -1) {
oval += cur;
fos.write(buf, 0, cur);
monitor.updateProgress(oval, len);
}
fos.close();
conn.disconnect();
}
public static boolean compareSHA1(File f, String sourceSHA) {
try {
String sha1_dst;
@ -864,7 +542,7 @@ public final class Tools {
Cursor cursor = ctx.getContentResolver().query(uri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
//result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} finally {
cursor.close();

View file

@ -1,6 +1,5 @@
package net.kdt.pojavlaunch;
import static net.kdt.pojavlaunch.MinecraftGLView.FINGER_SCROLL_THRESHOLD;
import static net.kdt.pojavlaunch.Tools.currentDisplayMetrics;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.DEFAULT_PREF;
@ -26,6 +25,7 @@ import org.lwjgl.glfw.CallbackBridge;
* Class dealing with the virtual mouse
*/
public class Touchpad extends FrameLayout {
private static final int FINGER_SCROLL_THRESHOLD = 10;
/* Whether the Touchpad should be displayed */
private boolean displayState;

View file

@ -0,0 +1,44 @@
package net.kdt.pojavlaunch.multirt;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.webkit.MimeTypeMap;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import net.kdt.pojavlaunch.BaseLauncherActivity;
import net.kdt.pojavlaunch.R;
public class MultiRTConfigDialog {
public static final int MULTIRT_PICK_RUNTIME = 2048;
public static final int MULTIRT_PICK_RUNTIME_STARTUP = 2049;
public AlertDialog dialog;
public RecyclerView dialogView;
public void prepare(BaseLauncherActivity ctx) {
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setTitle(R.string.multirt_config_title);
dialogView = new RecyclerView(ctx);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(ctx);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
dialogView.setLayoutManager(linearLayoutManager);
dialogView.setAdapter(new RTRecyclerViewAdapter(this));
builder.setView(dialogView);
builder.setPositiveButton(R.string.multirt_config_add, (dialog, which) -> openRuntimeSelector(ctx,MULTIRT_PICK_RUNTIME));
builder.setNegativeButton(R.string.mcn_exit_call, (dialog, which) -> dialog.cancel());
dialog = builder.create();
}
public void refresh() {
RecyclerView.Adapter adapter = dialogView.getAdapter();
if(adapter != null)dialogView.getAdapter().notifyDataSetChanged();
}
public static void openRuntimeSelector(Activity ctx, int code) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("xz");
if(mimeType == null) mimeType = "*/*";
intent.setType(mimeType);
ctx.startActivityForResult(intent,code);
}
}

View file

@ -0,0 +1,264 @@
package net.kdt.pojavlaunch.multirt;
import android.content.Context;
import android.system.Os;
import net.kdt.pojavlaunch.R;
import net.kdt.pojavlaunch.Tools;
import net.kdt.pojavlaunch.utils.JREUtils;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
public class MultiRTUtils {
public static HashMap<String,Runtime> cache = new HashMap<>();
public static class Runtime {
public Runtime(String name) {
this.name = name;
}
public String name;
public String versionString;
public String arch;
public int javaVersion;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Runtime runtime = (Runtime) o;
return name.equals(runtime.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
public static interface ProgressReporterThingy {
void reportStringProgress(int resid, Object ... stuff);
}
private static final File runtimeFolder = new File(Tools.MULTIRT_HOME);
private static final String JAVA_VERSION_str = "JAVA_VERSION=\"";
private static final String OS_ARCH_str = "OS_ARCH=\"";
public static List<Runtime> getRuntimes() {
if(!runtimeFolder.exists()) runtimeFolder.mkdirs();
ArrayList<Runtime> ret = new ArrayList<>();
System.out.println("Fetch runtime list");
for(File f : runtimeFolder.listFiles()) {
ret.add(read(f.getName()));
}
return ret;
}
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) { // lower - not useful
int currentFactor = r.javaVersion - majorVersion;
if(diff_factor > currentFactor) {
result = r.name;
diff_factor = currentFactor;
}
}
}
return result;
}
public static void installRuntimeNamed(InputStream runtimeInputStream, String name, ProgressReporterThingy thingy) throws IOException {
File dest = new File(runtimeFolder,"/"+name);
File tmp = new File(dest,"temporary");
if(dest.exists()) FileUtils.deleteDirectory(dest);
dest.mkdirs();
FileOutputStream fos = new FileOutputStream(tmp);
thingy.reportStringProgress(R.string.multirt_progress_caching);
IOUtils.copy(runtimeInputStream,fos);
fos.close();
runtimeInputStream.close();
uncompressTarXZ(tmp,dest,thingy);
tmp.delete();
read(name);
}
private static void __installRuntimeNamed__NoRM(InputStream runtimeInputStream, File dest, ProgressReporterThingy thingy) throws IOException {
File tmp = new File(dest,"temporary");
FileOutputStream fos = new FileOutputStream(tmp);
thingy.reportStringProgress(R.string.multirt_progress_caching);
IOUtils.copy(runtimeInputStream,fos);
fos.close();
runtimeInputStream.close();
uncompressTarXZ(tmp,dest,thingy);
tmp.delete();
}
public static void postPrepare(Context ctx, String name) throws IOException {
File dest = new File(runtimeFolder,"/"+name);
if(!dest.exists()) return;
Runtime r = read(name);
String libFolder = "lib";
if(new File(dest,libFolder+"/"+r.arch).exists()) libFolder = libFolder+"/"+r.arch;
File ftIn = new File(dest, libFolder+ "/libfreetype.so.6");
File ftOut = new File(dest, libFolder + "/libfreetype.so");
if (ftIn.exists() && (!ftOut.exists() || ftIn.length() != ftOut.length())) {
ftIn.renameTo(ftOut);
}
// Refresh libraries
copyDummyNativeLib(ctx,"libawt_xawt.so",dest,libFolder);
}
private static void copyDummyNativeLib(Context ctx, String name, File dest, String libFolder) throws IOException {
File fileLib = new File(dest, "/"+libFolder + "/" + name);
fileLib.delete();
FileInputStream is = new FileInputStream(new File(ctx.getApplicationInfo().nativeLibraryDir, name));
FileOutputStream os = new FileOutputStream(fileLib);
IOUtils.copy(is, os);
is.close();
os.close();
}
public static Runtime installRuntimeNamedBinpack(InputStream universalFileInputStream, InputStream platformBinsInputStream, String name, String binpackVersion, ProgressReporterThingy thingy) throws IOException {
File dest = new File(runtimeFolder,"/"+name);
if(dest.exists()) FileUtils.deleteDirectory(dest);
dest.mkdirs();
__installRuntimeNamed__NoRM(universalFileInputStream,dest,thingy);
__installRuntimeNamed__NoRM(platformBinsInputStream,dest,thingy);
File binpack_verfile = new File(runtimeFolder,"/"+name+"/pojav_version");
FileOutputStream fos = new FileOutputStream(binpack_verfile);
fos.write(binpackVersion.getBytes());
fos.close();
cache.remove(name); // Force reread
return read(name);
}
public static String __internal__readBinpackVersion(String name) {
File binpack_verfile = new File(runtimeFolder,"/"+name+"/pojav_version");
try {
if (binpack_verfile.exists()) {
return Tools.read(binpack_verfile.getAbsolutePath());
}else{
return null;
}
}catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static void removeRuntimeNamed(String name) throws IOException {
File dest = new File(runtimeFolder,"/"+name);
if(dest.exists()) {
FileUtils.deleteDirectory(dest);
cache.remove(name);
}
}
public static void setRuntimeNamed(Context ctx, String name) throws IOException {
File dest = new File(runtimeFolder,"/"+name);
if((!dest.exists()) || MultiRTUtils.forceReread(name).versionString == null) throw new RuntimeException("Selected runtime is broken!");
Tools.DIR_HOME_JRE = dest.getAbsolutePath();
JREUtils.relocateLibPath(ctx);
}
public static Runtime forceReread(String name) {
cache.remove(name);
return read(name);
}
public static Runtime read(String name) {
if(cache.containsKey(name)) return cache.get(name);
Runtime retur;
File release = new File(runtimeFolder,"/"+name+"/release");
if(!release.exists()) {
return new Runtime(name);
}
try {
String content = Tools.read(release.getAbsolutePath());
int _JAVA_VERSION_index = content.indexOf(JAVA_VERSION_str);
int _OS_ARCH_index = content.indexOf(OS_ARCH_str);
if(_JAVA_VERSION_index != -1 && _OS_ARCH_index != -1) {
_JAVA_VERSION_index += JAVA_VERSION_str.length();
_OS_ARCH_index += OS_ARCH_str.length();
String javaVersion = content.substring(_JAVA_VERSION_index,content.indexOf('"',_JAVA_VERSION_index));
String[] javaVersionSplit = javaVersion.split("\\.");
int javaVersionInt;
if (javaVersionSplit[0].equals("1")) {
javaVersionInt = Integer.parseInt(javaVersionSplit[1]);
} else {
javaVersionInt = Integer.parseInt(javaVersionSplit[0]);
}
Runtime r = new Runtime(name);
r.arch = content.substring(_OS_ARCH_index,content.indexOf('"',_OS_ARCH_index));
r.javaVersion = javaVersionInt;
r.versionString = javaVersion;
retur = r;
}else{
retur = new Runtime(name);
}
}catch(IOException e) {
retur = new Runtime(name);
}
cache.put(name,retur);
return retur;
}
private static void uncompressTarXZ(final File tarFile, final File dest, final ProgressReporterThingy thingy) throws IOException {
dest.mkdirs();
TarArchiveInputStream tarIn = null;
tarIn = new TarArchiveInputStream(
new XZCompressorInputStream(
new BufferedInputStream(
new FileInputStream(tarFile)
)
)
);
TarArchiveEntry tarEntry = tarIn.getNextTarEntry();
// tarIn is a TarArchiveInputStream
while (tarEntry != null) {
/*
* Unpacking very small files in short time cause
* application to ANR or out of memory, so delay
* a little if size is below than 20kb (20480 bytes)
*/
if (tarEntry.getSize() <= 20480) {
try {
// 40 small files per second
Thread.sleep(25);
} catch (InterruptedException ignored) {}
}
final String tarEntryName = tarEntry.getName();
// publishProgress(null, "Unpacking " + tarEntry.getName());
thingy.reportStringProgress(R.string.global_unpacking,tarEntryName);
File destPath = new File(dest, tarEntry.getName());
if (tarEntry.isSymbolicLink()) {
destPath.getParentFile().mkdirs();
try {
// android.system.Os
// Libcore one support all Android versions
Os.symlink(tarEntry.getName(), tarEntry.getLinkName());
} catch (Throwable e) {
e.printStackTrace();
}
} else if (tarEntry.isDirectory()) {
destPath.mkdirs();
destPath.setExecutable(true);
} else if (!destPath.exists() || destPath.length() != tarEntry.getSize()) {
destPath.getParentFile().mkdirs();
destPath.createNewFile();
FileOutputStream os = new FileOutputStream(destPath);
IOUtils.copy(tarIn, os);
os.close();
}
tarEntry = tarIn.getNextTarEntry();
}
tarIn.close();
}
}

View file

@ -0,0 +1,132 @@
package net.kdt.pojavlaunch.multirt;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.RecyclerView;
import net.kdt.pojavlaunch.R;
import net.kdt.pojavlaunch.Tools;
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
import java.io.IOException;
import java.util.List;
public class RTRecyclerViewAdapter extends RecyclerView.Adapter<RTRecyclerViewAdapter.RTViewHolder> {
MultiRTConfigDialog dialog;
public RTRecyclerViewAdapter(MultiRTConfigDialog dialog) {
this.dialog = dialog;
}
@NonNull
@Override
public RTViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View recyclableView = LayoutInflater.from(parent.getContext()).inflate(R.layout.multirt_recyclable_view,parent,false);
return new RTViewHolder(recyclableView);
}
@Override
public void onBindViewHolder(@NonNull RTViewHolder holder, int position) {
final List<MultiRTUtils.Runtime> runtimes = MultiRTUtils.getRuntimes();
holder.bindRuntime(runtimes.get(position),position);
}
public boolean isDefaultRuntime(MultiRTUtils.Runtime rt) {
return LauncherPreferences.PREF_DEFAULT_RUNTIME.equals(rt.name);
}
public void setDefault(MultiRTUtils.Runtime rt){
LauncherPreferences.PREF_DEFAULT_RUNTIME = rt.name;
LauncherPreferences.DEFAULT_PREF.edit().putString("defaultRuntime",LauncherPreferences.PREF_DEFAULT_RUNTIME).apply();
RTRecyclerViewAdapter.this.notifyDataSetChanged();
}
@Override
public int getItemCount() {
return MultiRTUtils.getRuntimes().size();
}
public class RTViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
final TextView javaVersionView;
final TextView fullJavaVersionView;
final ColorStateList defaultColors;
final Button setDefaultButton;
final Context ctx;
MultiRTUtils.Runtime currentRuntime;
int currentPosition;
public RTViewHolder(View itemView) {
super(itemView);
javaVersionView = itemView.findViewById(R.id.multirt_view_java_version);
fullJavaVersionView = itemView.findViewById(R.id.multirt_view_java_version_full);
itemView.findViewById(R.id.multirt_view_removebtn).setOnClickListener(this);
setDefaultButton = itemView.findViewById(R.id.multirt_view_setdefaultbtn);
setDefaultButton.setOnClickListener(this);
defaultColors = fullJavaVersionView.getTextColors();
ctx = itemView.getContext();
}
public void bindRuntime(MultiRTUtils.Runtime rt, int pos) {
currentRuntime = rt;
currentPosition = pos;
if(rt.versionString != null) {
javaVersionView.setText(ctx.getString(R.string.multirt_java_ver, rt.name, rt.javaVersion));
fullJavaVersionView.setText(rt.versionString);
fullJavaVersionView.setTextColor(defaultColors);
setDefaultButton.setVisibility(View.VISIBLE);
boolean default_ = isDefaultRuntime(rt);
setDefaultButton.setEnabled(!default_);
setDefaultButton.setText(default_?R.string.multirt_config_setdefault_already:R.string.multirt_config_setdefault);
}else{
javaVersionView.setText(rt.name);
fullJavaVersionView.setText(R.string.multirt_runtime_corrupt);
fullJavaVersionView.setTextColor(Color.RED);
setDefaultButton.setVisibility(View.GONE);
}
}
@Override
public void onClick(View v) {
if(v.getId() == R.id.multirt_view_removebtn) {
if (currentRuntime != null) {
if(MultiRTUtils.getRuntimes().size() < 2) {
AlertDialog.Builder bldr = new AlertDialog.Builder(ctx);
bldr.setTitle(R.string.global_error);
bldr.setMessage(R.string.multirt_config_removeerror_last);
bldr.setPositiveButton(android.R.string.ok,(adapter, which)->adapter.dismiss());
bldr.show();
return;
}
final ProgressDialog barrier = new ProgressDialog(ctx);
barrier.setMessage(ctx.getString(R.string.global_waiting));
barrier.setProgressStyle(ProgressDialog.STYLE_SPINNER);
barrier.setCancelable(false);
barrier.show();
Thread t = new Thread(() -> {
try {
MultiRTUtils.removeRuntimeNamed(currentRuntime.name);
} catch (IOException e) {
Tools.showError(itemView.getContext(), e);
}
v.post(() -> {
if(isDefaultRuntime(currentRuntime)) setDefault(MultiRTUtils.getRuntimes().get(0));
barrier.dismiss();
RTRecyclerViewAdapter.this.notifyDataSetChanged();
dialog.dialog.show();
});
});
t.start();
}
}else if(v.getId() == R.id.multirt_view_setdefaultbtn) {
if(currentRuntime != null) {
setDefault(currentRuntime);
RTRecyclerViewAdapter.this.notifyDataSetChanged();
}
}
}
}
}

View file

@ -0,0 +1,103 @@
package net.kdt.pojavlaunch.multirt;
import android.content.Context;
import android.database.DataSetObserver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.kdt.pojavlaunch.R;
import java.util.List;
public class RTSpinnerAdapter implements SpinnerAdapter {
final Context ctx;
List<MultiRTUtils.Runtime> runtimes;
public RTSpinnerAdapter(@NonNull Context context, List<MultiRTUtils.Runtime> runtimes) {
this.runtimes = runtimes;
MultiRTUtils.Runtime runtime = new MultiRTUtils.Runtime("<Default>");
runtime.versionString = "";
this.runtimes.add(runtime);
ctx = context;
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
}
@Override
public int getCount() {
return runtimes.size();
}
@Override
public Object getItem(int position) {
return runtimes.get(position);
}
@Override
public long getItemId(int position) {
return runtimes.get(position).name.hashCode();
}
@Override
public boolean hasStableIds() {
return true;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View v = convertView!=null?
convertView:
LayoutInflater.from(ctx).inflate(R.layout.multirt_recyclable_view,parent,false);
MultiRTUtils.Runtime rt = runtimes.get(position);
final TextView javaVersionView = v.findViewById(R.id.multirt_view_java_version);
final TextView fullJavaVersionView = v.findViewById(R.id.multirt_view_java_version_full);
v.findViewById(R.id.multirt_view_removebtn).setVisibility(View.GONE);
v.findViewById(R.id.multirt_view_setdefaultbtn).setVisibility(View.GONE);
if(rt.versionString != null) {
javaVersionView.setText(ctx.getString(R.string.multirt_java_ver, rt.name, rt.javaVersion));
fullJavaVersionView.setText(rt.versionString);
}else{
javaVersionView.setText(rt.name);
fullJavaVersionView.setText(R.string.multirt_runtime_corrupt);
}
return v;
}
@Override
public int getItemViewType(int position) {
return 0;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public boolean isEmpty() {
return runtimes.isEmpty();
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return getView(position,convertView,parent);
}
}

View file

@ -6,7 +6,6 @@ import android.util.AttributeSet;
import androidx.preference.Preference;
import net.kdt.pojavlaunch.R;
import net.kdt.pojavlaunch.extra.ExtraCore;
public class BackButtonPreference extends Preference {
public BackButtonPreference(Context context, AttributeSet attrs) {
@ -31,6 +30,5 @@ public class BackButtonPreference extends Preference {
@Override
protected void onClick() {
// It is caught by an ExtraListener in the LauncherActivity
ExtraCore.setValue("back_preference", "true");
}
}

View file

@ -318,9 +318,6 @@ public class JREUtils {
if (exitCode != 0) {
activity.runOnUiThread(() -> {
AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
dialog.setMessage(activity.getString(R.string.mcn_exit_title, exitCode));
dialog.setPositiveButton(android.R.string.ok, (p1, p2) -> BaseMainActivity.fullyExit());
dialog.show();
});
}

View file

@ -122,9 +122,6 @@ public class CallbackBridge {
public static String accessAndroidClipboard(int type, String copy) {
switch (type) {
case CLIPBOARD_COPY:
BaseMainActivity.GLOBAL_CLIPBOARD.setPrimaryClip(ClipData.newPlainText("Copy", copy));
return null;
case CLIPBOARD_PASTE:
if (BaseMainActivity.GLOBAL_CLIPBOARD.hasPrimaryClip() && BaseMainActivity.GLOBAL_CLIPBOARD.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
return BaseMainActivity.GLOBAL_CLIPBOARD.getPrimaryClip().getItemAt(0).getText().toString();

View file

@ -80,8 +80,6 @@ void custom_exit(int code) {
JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_setupExitTrap(JNIEnv *env, jclass clazz, jobject context) {
exitTrap_ctx = (*env)->NewGlobalRef(env,context);
(*env)->GetJavaVM(env,&exitTrap_jvm);
exitTrap_exitClass = (*env)->NewGlobalRef(env,(*env)->FindClass(env,"net/kdt/pojavlaunch/ExitActivity"));
exitTrap_staticMethod = (*env)->GetStaticMethodID(env,exitTrap_exitClass,"showExitMessage","(Landroid/content/Context;I)V");
xhook_enable_debug(1);
xhook_register(".*\\.so$","exit",custom_exit,&old_exit);
xhook_refresh(1);

View file

@ -20,10 +20,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<net.kdt.pojavlaunch.MinecraftGLView
android:id="@+id/main_game_render_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<net.kdt.pojavlaunch.Touchpad
android:layout_height="match_parent"