mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-16 08:05:34 -04:00
Cleanup, part 2
This commit is contained in:
parent
57b37dfc8c
commit
8e669caa2e
@ -591,7 +591,7 @@ public class AWTInputEvent {
|
||||
/**
|
||||
* Constant for the Microsoft Windows "Windows" key.
|
||||
* It is used for both the left and right version of the key.
|
||||
* @see #getKeyLocation()
|
||||
* see getKeyLocation
|
||||
* @since 1.5
|
||||
*/
|
||||
public static final int VK_WINDOWS = 0x020C;
|
||||
@ -888,25 +888,25 @@ public class AWTInputEvent {
|
||||
public static final int MOUSE_WHEEL = 7 + MOUSE_FIRST;
|
||||
|
||||
/**
|
||||
* Indicates no mouse buttons; used by {@link #getButton}.
|
||||
* Indicates no mouse buttons; used by getButton.
|
||||
* @since 1.4
|
||||
*/
|
||||
public static final int NOBUTTON = 0;
|
||||
|
||||
/**
|
||||
* Indicates mouse button #1; used by {@link #getButton}.
|
||||
* Indicates mouse button #1; used by getButton.
|
||||
* @since 1.4
|
||||
*/
|
||||
public static final int BUTTON1 = 1;
|
||||
|
||||
/**
|
||||
* Indicates mouse button #2; used by {@link #getButton}.
|
||||
* Indicates mouse button #2; used by getButton.
|
||||
* @since 1.4
|
||||
*/
|
||||
public static final int BUTTON2 = 2;
|
||||
|
||||
/**
|
||||
* Indicates mouse button #3; used by {@link #getButton}.
|
||||
* Indicates mouse button #3; used by getButton.
|
||||
* @since 1.4
|
||||
*/
|
||||
public static final int BUTTON3 = 3;
|
||||
|
@ -6,11 +6,11 @@ import android.os.Build;
|
||||
* This class aims at providing a simple and easy way to deal with the device architecture.
|
||||
*/
|
||||
public class Architecture {
|
||||
public static int UNSUPPORTED_ARCH = -1;
|
||||
public static int ARCH_ARM64 = 0x1;
|
||||
public static int ARCH_ARM = 0x2;
|
||||
public static int ARCH_X86 = 0x4;
|
||||
public static int ARCH_X86_64 = 0x8;
|
||||
public static final int UNSUPPORTED_ARCH = -1;
|
||||
public static final int ARCH_ARM64 = 0x1;
|
||||
public static final int ARCH_ARM = 0x2;
|
||||
public static final int ARCH_X86 = 0x4;
|
||||
public static final int ARCH_X86_64 = 0x8;
|
||||
|
||||
/**
|
||||
* Tell us if the device supports 64 bits architecture
|
||||
@ -58,14 +58,6 @@ public class Architecture {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell is the device is based on an arm processor.
|
||||
* It doesn't tell if the device is 64 or 32 bits.
|
||||
* @return Whether or not the device is arm based.
|
||||
*/
|
||||
public static boolean isArmDevice(){
|
||||
return !isx86Device();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -28,6 +28,7 @@ import java.io.OutputStream;
|
||||
/**
|
||||
* An activity dedicated to importing control files.
|
||||
*/
|
||||
@SuppressWarnings("IOStreamConstructor")
|
||||
public class ImportControlActivity extends Activity {
|
||||
|
||||
private Uri mUriData;
|
||||
@ -75,7 +76,7 @@ public class ImportControlActivity extends Activity {
|
||||
//Import and verify thread
|
||||
//Kill the app if the file isn't valid.
|
||||
new Thread(() -> {
|
||||
importControlFile("TMP_IMPORT_FILE");
|
||||
importControlFile();
|
||||
|
||||
if(verify())mIsFileVerified = true;
|
||||
else runOnUiThread(() -> {
|
||||
@ -118,23 +119,19 @@ public class ImportControlActivity extends Activity {
|
||||
|
||||
/**
|
||||
* Copy a the file from the Intent data with a provided name into the controlmap folder.
|
||||
* @param fileName The file name to use.
|
||||
* @return whether the file was successfully imported
|
||||
*/
|
||||
private boolean importControlFile(String fileName){
|
||||
private void importControlFile(){
|
||||
InputStream is;
|
||||
try {
|
||||
is = getContentResolver().openInputStream(mUriData);
|
||||
OutputStream os = new FileOutputStream(Tools.CTRLMAP_PATH + "/" + fileName + ".json");
|
||||
OutputStream os = new FileOutputStream(Tools.CTRLMAP_PATH + "/" + "TMP_IMPORT_FILE" + ".json");
|
||||
IOUtils.copy(is, os);
|
||||
|
||||
os.close();
|
||||
is.close();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -146,9 +143,7 @@ public class ImportControlActivity extends Activity {
|
||||
fileName = trimFileName(fileName);
|
||||
|
||||
if(fileName.isEmpty()) return false;
|
||||
if (FileUtils.exists(Tools.CTRLMAP_PATH + "/" + fileName + ".json")) return false;
|
||||
|
||||
return true;
|
||||
return !FileUtils.exists(Tools.CTRLMAP_PATH + "/" + fileName + ".json");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,32 +3,41 @@ package net.kdt.pojavlaunch;
|
||||
import static net.kdt.pojavlaunch.MainActivity.fullyExit;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.*;
|
||||
import android.util.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import com.kdt.LoggerView;
|
||||
|
||||
import net.kdt.pojavlaunch.customcontrols.keyboard.AwtCharSender;
|
||||
import net.kdt.pojavlaunch.customcontrols.keyboard.TouchCharInput;
|
||||
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
|
||||
import net.kdt.pojavlaunch.multirt.Runtime;
|
||||
import net.kdt.pojavlaunch.prefs.*;
|
||||
import net.kdt.pojavlaunch.utils.*;
|
||||
import org.lwjgl.glfw.*;
|
||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||
import net.kdt.pojavlaunch.utils.JREUtils;
|
||||
import net.kdt.pojavlaunch.utils.MathUtils;
|
||||
|
||||
import com.kdt.LoggerView;
|
||||
import org.lwjgl.glfw.CallbackBridge;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouchListener {
|
||||
private static final int MSG_LEFT_MOUSE_BUTTON_CHECK = 1028;
|
||||
|
||||
|
||||
private AWTCanvasView mTextureView;
|
||||
private LoggerView mLoggerView;
|
||||
private TouchCharInput mTouchCharInput;
|
||||
@ -128,7 +137,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
|
||||
|
||||
try {
|
||||
|
||||
placeMouseAt(CallbackBridge.physicalWidth / 2, CallbackBridge.physicalHeight / 2);
|
||||
placeMouseAt(CallbackBridge.physicalWidth / 2f, CallbackBridge.physicalHeight / 2f);
|
||||
|
||||
final File modFile = (File) getIntent().getExtras().getSerializable("modFile");
|
||||
final String javaArgs = getIntent().getExtras().getString("javaArgs");
|
||||
@ -188,6 +197,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
|
||||
|
||||
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent e) {
|
||||
boolean isDown;
|
||||
@ -231,16 +241,12 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
|
||||
return true;
|
||||
}
|
||||
|
||||
public void placeMouseAdd(float x, float y) {
|
||||
mMousePointerImageView.setX(mMousePointerImageView.getX() + x);
|
||||
mMousePointerImageView.setY(mMousePointerImageView.getY() + y);
|
||||
}
|
||||
|
||||
public void placeMouseAt(float x, float y) {
|
||||
mMousePointerImageView.setX(x);
|
||||
mMousePointerImageView.setY(y);
|
||||
}
|
||||
|
||||
@SuppressWarnings("SuspiciousNameCombination")
|
||||
void sendScaledMousePosition(float x, float y){
|
||||
// Clamp positions to the borders of the usable view, then scale them
|
||||
x = androidx.core.math.MathUtils.clamp(x, mTextureView.getX(), mTextureView.getX() + mTextureView.getWidth());
|
||||
@ -260,14 +266,6 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
|
||||
mLoggerView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
public void closeLogOutput(View view) {
|
||||
if (mSkipDetectMod) {
|
||||
mLoggerView.setVisibility(View.GONE);
|
||||
} else {
|
||||
forceClose(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleVirtualMouse(View v) {
|
||||
mIsVirtualMouseEnabled = !mIsVirtualMouseEnabled;
|
||||
mTouchPad.setVisibility(mIsVirtualMouseEnabled ? View.VISIBLE : View.GONE);
|
||||
@ -279,7 +277,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
|
||||
public int launchJavaRuntime(File modFile, String javaArgs) {
|
||||
JREUtils.redirectAndPrintJRELog();
|
||||
try {
|
||||
List<String> javaArgList = new ArrayList<String>();
|
||||
List<String> javaArgList = new ArrayList<>();
|
||||
|
||||
// Enable Caciocavallo
|
||||
Tools.getCacioJavaArgs(javaArgList,MultiRTUtils.getSelectedRuntime().javaVersion == 8);
|
||||
@ -311,7 +309,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
|
||||
|
||||
|
||||
|
||||
private int doCustomInstall(File modFile, String javaArgs) throws IOException {
|
||||
private int doCustomInstall(File modFile, String javaArgs) {
|
||||
mSkipDetectMod = true;
|
||||
return launchJavaRuntime(modFile, javaArgs);
|
||||
}
|
||||
|
@ -230,6 +230,7 @@ public class LauncherActivity extends BaseActivity {
|
||||
LauncherPreferences.computeNotchSize(this);
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private Fragment getVisibleFragment(String tag){
|
||||
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
|
||||
if(fragment != null && fragment.isVisible()) {
|
||||
@ -238,6 +239,7 @@ public class LauncherActivity extends BaseActivity {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private Fragment getVisibleFragment(int id){
|
||||
Fragment fragment = getSupportFragmentManager().findFragmentById(id);
|
||||
if(fragment != null && fragment.isVisible()) {
|
||||
|
@ -12,7 +12,7 @@ import java.lang.ref.WeakReference;
|
||||
*/
|
||||
@Keep
|
||||
public class Logger {
|
||||
private static Logger sLoggerSingleton = null;
|
||||
private static volatile Logger sLoggerSingleton = null;
|
||||
|
||||
/* Instance variables */
|
||||
private final File mLogFile;
|
||||
@ -21,11 +21,7 @@ public class Logger {
|
||||
|
||||
/* No public construction */
|
||||
private Logger(){
|
||||
this("latestlog.txt");
|
||||
}
|
||||
|
||||
private Logger(String fileName){
|
||||
mLogFile = new File(Tools.DIR_GAME_HOME, fileName);
|
||||
mLogFile = new File(Tools.DIR_GAME_HOME, "latestlog.txt");
|
||||
// Make a new instance of the log file
|
||||
// Default PrintStream constructor will overwrite the file for us
|
||||
try {
|
||||
@ -66,11 +62,6 @@ public class Logger {
|
||||
}catch (IOException e){ e.printStackTrace();}
|
||||
}
|
||||
|
||||
/** Disables the printing */
|
||||
public void shutdown(){
|
||||
mLogStream.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform various checks to see if the log is safe to print
|
||||
* Subclasses may want to override this behavior
|
||||
|
@ -174,10 +174,10 @@ public class LwjglGlfwKeycode {
|
||||
/** If this bit is set one or more Super keys were held down. */
|
||||
public static final int GLFW_MOD_SUPER = 0x8;
|
||||
|
||||
/** If this bit is set the Caps Lock key is enabled and the {@link #GLFW_LOCK_KEY_MODS LOCK_KEY_MODS} input mode is set. */
|
||||
/** If this bit is set the Caps Lock key is enabled and the LOCK_KEY_MODS input mode is set. */
|
||||
public static final int GLFW_MOD_CAPS_LOCK = 0x10;
|
||||
|
||||
/** If this bit is set the Num Lock key is enabled and the {@link #GLFW_LOCK_KEY_MODS LOCK_KEY_MODS} input mode is set. */
|
||||
/** If this bit is set the Num Lock key is enabled and the LOCK_KEY_MODS input mode is set. */
|
||||
public static final int GLFW_MOD_NUM_LOCK = 0x20;
|
||||
|
||||
|
||||
|
@ -51,8 +51,6 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
|
||||
|
||||
volatile public static boolean isInputStackCall;
|
||||
|
||||
public float scaleFactor = 1;
|
||||
|
||||
public static TouchCharInput touchCharInput;
|
||||
private MinecraftGLSurface minecraftGLView;
|
||||
private static Touchpad touchpad;
|
||||
@ -81,7 +79,7 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
|
||||
mProfile = PojavProfile.getCurrentProfileContent(this, null);
|
||||
if(LauncherProfiles.mainProfileJson == null) LauncherProfiles.update();
|
||||
minecraftProfile = LauncherProfiles.mainProfileJson.profiles.get(LauncherPreferences.DEFAULT_PREF.getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE,""));
|
||||
MCOptionUtils.load(Tools.getGameDirPath(minecraftProfile));
|
||||
MCOptionUtils.load(Tools.getGameDirPath(minecraftProfile).getAbsolutePath());
|
||||
GameService.startService(this);
|
||||
initLayout(R.layout.activity_basemain);
|
||||
CallbackBridge.addGrabListener(touchpad);
|
||||
@ -155,8 +153,8 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
|
||||
CallbackBridge.nativeSetUseInputStackQueue(isInputStackCall);
|
||||
|
||||
Tools.getDisplayMetrics(this);
|
||||
windowWidth = Tools.getDisplayFriendlyRes(currentDisplayMetrics.widthPixels, scaleFactor);
|
||||
windowHeight = Tools.getDisplayFriendlyRes(currentDisplayMetrics.heightPixels, scaleFactor);
|
||||
windowWidth = Tools.getDisplayFriendlyRes(currentDisplayMetrics.widthPixels, 1f);
|
||||
windowHeight = Tools.getDisplayFriendlyRes(currentDisplayMetrics.heightPixels, 1f);
|
||||
|
||||
|
||||
// Menu
|
||||
|
@ -54,6 +54,7 @@ public class MinecraftGLSurface extends View implements GrabListener{
|
||||
private final TapDetector mDoubleTapDetector = new TapDetector(2, TapDetector.DETECTION_METHOD_DOWN);
|
||||
/* MC GUI scale, listened by MCOptionUtils */
|
||||
private int mGuiScale;
|
||||
@SuppressWarnings("FieldCanBeLocal") // it can't, otherwise the weak reference will disappear
|
||||
private final MCOptionUtils.MCOptionListener mGuiScaleListener = () -> mGuiScale = getMcScale();
|
||||
/* Surface ready listener, used by the activity to launch minecraft */
|
||||
SurfaceReadyListener mSurfaceReadyListener = null;
|
||||
|
@ -22,8 +22,8 @@ import net.kdt.pojavlaunch.tasks.AsyncAssetManager;
|
||||
import net.kdt.pojavlaunch.utils.*;
|
||||
|
||||
public class PojavApplication extends Application {
|
||||
public static String CRASH_REPORT_TAG = "PojavCrashReport";
|
||||
public static ExecutorService sExecutorService = new ThreadPoolExecutor(4, 4, 500, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
|
||||
public static final String CRASH_REPORT_TAG = "PojavCrashReport";
|
||||
public static final ExecutorService sExecutorService = new ThreadPoolExecutor(4, 4, 500, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
@ -74,7 +74,7 @@ public class PojavApplication extends Application {
|
||||
originalJNIDirectory.lastIndexOf("/"))
|
||||
.concat("/x86");
|
||||
}
|
||||
AsyncAssetManager.unpackRuntime(getAssets(), false);
|
||||
AsyncAssetManager.unpackRuntime(getAssets());
|
||||
} catch (Throwable throwable) {
|
||||
Intent ferrorIntent = new Intent(this, FatalErrorActivity.class);
|
||||
ferrorIntent.putExtra("throwable", throwable);
|
||||
|
@ -1,44 +1,38 @@
|
||||
package net.kdt.pojavlaunch;
|
||||
|
||||
import android.app.*;
|
||||
import android.content.*;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.Cursor;
|
||||
import android.net.*;
|
||||
import android.os.*;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.util.*;
|
||||
import com.google.gson.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.nio.charset.*;
|
||||
import java.util.*;
|
||||
|
||||
import net.kdt.pojavlaunch.extra.ExtraConstants;
|
||||
import net.kdt.pojavlaunch.extra.ExtraCore;
|
||||
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
|
||||
import net.kdt.pojavlaunch.plugins.FFmpegPlugin;
|
||||
import net.kdt.pojavlaunch.prefs.*;
|
||||
import net.kdt.pojavlaunch.utils.*;
|
||||
import net.kdt.pojavlaunch.value.*;
|
||||
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
|
||||
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
|
||||
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.lwjgl.glfw.*;
|
||||
import android.view.*;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.os.Build.VERSION_CODES.P;
|
||||
import static net.kdt.pojavlaunch.PojavApplication.sExecutorService;
|
||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_IGNORE_NOTCH;
|
||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_NOTCH_SIZE;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
@ -46,9 +40,42 @@ import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
public final class Tools {
|
||||
public static final boolean ENABLE_DEV_FEATURES = BuildConfig.DEBUG;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
|
||||
import net.kdt.pojavlaunch.plugins.FFmpegPlugin;
|
||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||
import net.kdt.pojavlaunch.utils.DownloadUtils;
|
||||
import net.kdt.pojavlaunch.utils.JREUtils;
|
||||
import net.kdt.pojavlaunch.utils.JSONUtils;
|
||||
import net.kdt.pojavlaunch.utils.OldVersionsUtils;
|
||||
import net.kdt.pojavlaunch.value.DependentLibrary;
|
||||
import net.kdt.pojavlaunch.value.MinecraftAccount;
|
||||
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
|
||||
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
|
||||
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.lwjgl.glfw.CallbackBridge;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("IOStreamConstructor")
|
||||
public final class Tools {
|
||||
public static String APP_NAME = "null";
|
||||
|
||||
public static final Gson GLOBAL_GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||
@ -60,14 +87,13 @@ public final class Tools {
|
||||
public static String MULTIRT_HOME;
|
||||
public static String LOCAL_RENDERER = null;
|
||||
public static int DEVICE_ARCHITECTURE;
|
||||
public static String LAUNCHERPROFILES_RTPREFIX = "pojav://";
|
||||
public static final String LAUNCHERPROFILES_RTPREFIX = "pojav://";
|
||||
|
||||
// New since 3.3.1
|
||||
public static String DIR_ACCOUNT_NEW;
|
||||
public static String DIR_ACCOUNT_OLD;
|
||||
public static String DIR_GAME_HOME = Environment.getExternalStorageDirectory().getAbsolutePath() + "/games/PojavLauncher";
|
||||
public static String DIR_GAME_NEW;
|
||||
public static String DIR_GAME_OLD = Environment.getExternalStorageDirectory().getAbsolutePath() + "/games/.minecraft";
|
||||
|
||||
// New since 3.0.0
|
||||
public static String DIR_HOME_JRE;
|
||||
@ -83,8 +109,6 @@ public final class Tools {
|
||||
public static String OBSOLETE_RESOURCES_PATH;
|
||||
public static String CTRLMAP_PATH;
|
||||
public static String CTRLDEF_FILE;
|
||||
|
||||
public static final String LIBNAME_OPTIFINE = "optifine:OptiFine";
|
||||
public static final int RUN_MOD_INSTALLER = 2050;
|
||||
|
||||
|
||||
@ -130,13 +154,12 @@ public final class Tools {
|
||||
|
||||
public static void launchMinecraft(final Activity activity, MinecraftAccount minecraftAccount,
|
||||
MinecraftProfile minecraftProfile, String versionId) throws Throwable {
|
||||
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
|
||||
((ActivityManager)activity.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryInfo(mi);
|
||||
if(LauncherPreferences.PREF_RAM_ALLOCATION > (mi.availMem/1048576L)) {
|
||||
int freeDeviceMemory = getFreeDeviceMemory(activity);
|
||||
if(LauncherPreferences.PREF_RAM_ALLOCATION > freeDeviceMemory) {
|
||||
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))
|
||||
.setMessage(activity.getString(R.string.memory_warning_msg, freeDeviceMemory ,LauncherPreferences.PREF_RAM_ALLOCATION))
|
||||
.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {synchronized(memoryErrorLock){memoryErrorLock.notifyAll();}})
|
||||
.setOnCancelListener((i) -> {synchronized(memoryErrorLock){memoryErrorLock.notifyAll();}});
|
||||
b.show();
|
||||
@ -147,12 +170,12 @@ public final class Tools {
|
||||
}
|
||||
JMinecraftVersionList.Version versionInfo = Tools.getVersionInfo(versionId);
|
||||
LauncherProfiles.update();
|
||||
String gamedirPath = Tools.getGameDirPath(minecraftProfile);
|
||||
File gamedir = Tools.getGameDirPath(minecraftProfile);
|
||||
|
||||
|
||||
// Pre-process specific files
|
||||
disableSplash(gamedirPath);
|
||||
String[] launchArgs = getMinecraftClientArgs(minecraftAccount, versionInfo, gamedirPath);
|
||||
disableSplash(gamedir);
|
||||
String[] launchArgs = getMinecraftClientArgs(minecraftAccount, versionInfo, gamedir);
|
||||
|
||||
// Select the appropriate openGL version
|
||||
OldVersionsUtils.selectOpenGlVersion(versionInfo);
|
||||
@ -160,7 +183,7 @@ public final class Tools {
|
||||
|
||||
String launchClassPath = generateLaunchClassPath(versionInfo, versionId);
|
||||
|
||||
List<String> javaArgList = new ArrayList<String>();
|
||||
List<String> javaArgList = new ArrayList<>();
|
||||
|
||||
getCacioJavaArgs(javaArgList, MultiRTUtils.getSelectedRuntime().javaVersion == 8);
|
||||
|
||||
@ -171,7 +194,7 @@ public final class Tools {
|
||||
}
|
||||
javaArgList.add("-Dlog4j.configurationFile=" + configFile);
|
||||
}
|
||||
javaArgList.addAll(Arrays.asList(getMinecraftJVMArgs(versionId, gamedirPath)));
|
||||
javaArgList.addAll(Arrays.asList(getMinecraftJVMArgs(versionId, gamedir)));
|
||||
javaArgList.add("-cp");
|
||||
javaArgList.add(getLWJGL3ClassPath() + ":" + launchClassPath);
|
||||
|
||||
@ -181,17 +204,17 @@ public final class Tools {
|
||||
FFmpegPlugin.discover(activity);
|
||||
String args = LauncherPreferences.PREF_CUSTOM_JAVA_ARGS;
|
||||
if(Tools.isValidString(minecraftProfile.javaArgs)) args = minecraftProfile.javaArgs;
|
||||
JREUtils.launchJavaVM(activity, gamedirPath, javaArgList, args);
|
||||
JREUtils.launchJavaVM(activity, gamedir, javaArgList, args);
|
||||
}
|
||||
|
||||
public static String getGameDirPath(@NonNull MinecraftProfile minecraftProfile){
|
||||
public static File getGameDirPath(@NonNull MinecraftProfile minecraftProfile){
|
||||
if(minecraftProfile.gameDir != null){
|
||||
if(minecraftProfile.gameDir.startsWith(Tools.LAUNCHERPROFILES_RTPREFIX))
|
||||
return minecraftProfile.gameDir.replace(Tools.LAUNCHERPROFILES_RTPREFIX,Tools.DIR_GAME_HOME+"/");
|
||||
return new File(minecraftProfile.gameDir.replace(Tools.LAUNCHERPROFILES_RTPREFIX,Tools.DIR_GAME_HOME+"/"));
|
||||
else
|
||||
return Tools.DIR_GAME_HOME + '/' + minecraftProfile.gameDir;
|
||||
return new File(Tools.DIR_GAME_HOME,minecraftProfile.gameDir);
|
||||
}
|
||||
return Tools.DIR_GAME_NEW;
|
||||
return new File(Tools.DIR_GAME_NEW);
|
||||
}
|
||||
|
||||
public static void buildNotificationChannel(Context context){
|
||||
@ -202,26 +225,24 @@ public final class Tools {
|
||||
NotificationManagerCompat manager = NotificationManagerCompat.from(context);
|
||||
manager.createNotificationChannel(channel);
|
||||
}
|
||||
|
||||
private static boolean mkdirs(String path) {
|
||||
File file = new File(path);
|
||||
return file.mkdirs();
|
||||
}
|
||||
|
||||
public static void disableSplash(String dir) {
|
||||
mkdirs(dir + "/config");
|
||||
File forgeSplashFile = new File(dir, "config/splash.properties");
|
||||
String forgeSplashContent = "enabled=true";
|
||||
try {
|
||||
if (forgeSplashFile.exists()) {
|
||||
forgeSplashContent = Tools.read(forgeSplashFile.getAbsolutePath());
|
||||
public static void disableSplash(File dir) {
|
||||
File configDir = new File(dir, "config");
|
||||
if(configDir.exists() || configDir.mkdirs()) {
|
||||
File forgeSplashFile = new File(dir, "config/splash.properties");
|
||||
String forgeSplashContent = "enabled=true";
|
||||
try {
|
||||
if (forgeSplashFile.exists()) {
|
||||
forgeSplashContent = Tools.read(forgeSplashFile.getAbsolutePath());
|
||||
}
|
||||
if (forgeSplashContent.contains("enabled=true")) {
|
||||
Tools.write(forgeSplashFile.getAbsolutePath(),
|
||||
forgeSplashContent.replace("enabled=true", "enabled=false"));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(Tools.APP_NAME, "Could not disable Forge 1.12.2 and below splash screen!", e);
|
||||
}
|
||||
if (forgeSplashContent.contains("enabled=true")) {
|
||||
Tools.write(forgeSplashFile.getAbsolutePath(),
|
||||
forgeSplashContent.replace("enabled=true", "enabled=false"));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(Tools.APP_NAME, "Could not disable Forge 1.12.2 and below splash screen!", e);
|
||||
} else {
|
||||
Log.w(Tools.APP_NAME, "Failed to create the configuration directory");
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,19 +282,20 @@ public final class Tools {
|
||||
}
|
||||
|
||||
StringBuilder cacioClasspath = new StringBuilder();
|
||||
cacioClasspath.append("-Xbootclasspath/" + (isJava8 ? "p" : "a"));
|
||||
cacioClasspath.append("-Xbootclasspath/").append(isJava8 ? "p" : "a");
|
||||
File cacioDir = new File(DIR_GAME_HOME + "/caciocavallo" + (isJava8 ? "" : "17"));
|
||||
if (cacioDir.exists() && cacioDir.isDirectory()) {
|
||||
for (File file : cacioDir.listFiles()) {
|
||||
File[] cacioFiles = cacioDir.listFiles();
|
||||
if (cacioFiles != null) {
|
||||
for (File file : cacioFiles) {
|
||||
if (file.getName().endsWith(".jar")) {
|
||||
cacioClasspath.append(":" + file.getAbsolutePath());
|
||||
cacioClasspath.append(":").append(file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
javaArgList.add(cacioClasspath.toString());
|
||||
}
|
||||
|
||||
public static String[] getMinecraftJVMArgs(String versionName, String strGameDir) {
|
||||
public static String[] getMinecraftJVMArgs(String versionName, File gameDir) {
|
||||
JMinecraftVersionList.Version versionInfo = Tools.getVersionInfo(versionName, true);
|
||||
// Parse Forge 1.17+ additional JVM Arguments
|
||||
if (versionInfo.inheritsFrom == null || versionInfo.arguments == null || versionInfo.arguments.jvm == null) {
|
||||
@ -282,39 +304,22 @@ public final class Tools {
|
||||
|
||||
Map<String, String> varArgMap = new ArrayMap<>();
|
||||
varArgMap.put("classpath_separator", ":");
|
||||
varArgMap.put("library_directory", strGameDir + "/libraries");
|
||||
varArgMap.put("library_directory", new File(gameDir, "libraries").getAbsolutePath());
|
||||
varArgMap.put("version_name", versionInfo.id);
|
||||
varArgMap.put("natives_directory", Tools.NATIVE_LIB_DIR);
|
||||
|
||||
List<String> minecraftArgs = new ArrayList<String>();
|
||||
List<String> minecraftArgs = new ArrayList<>();
|
||||
if (versionInfo.arguments != null) {
|
||||
for (Object arg : versionInfo.arguments.jvm) {
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
} //TODO: implement (?maybe?)
|
||||
}
|
||||
}
|
||||
|
||||
String[] argsFromJson = JSONUtils.insertJSONValueList(minecraftArgs.toArray(new String[0]), varArgMap);
|
||||
// Tools.dialogOnUiThread(this, "Result args", Arrays.asList(argsFromJson).toString());
|
||||
return argsFromJson;
|
||||
return JSONUtils.insertJSONValueList(minecraftArgs.toArray(new String[0]), varArgMap);
|
||||
}
|
||||
|
||||
public static String[] getMinecraftClientArgs(MinecraftAccount profile, JMinecraftVersionList.Version versionInfo, String strGameDir) {
|
||||
public static String[] getMinecraftClientArgs(MinecraftAccount profile, JMinecraftVersionList.Version versionInfo, File gameDir) {
|
||||
String username = profile.username;
|
||||
String versionName = versionInfo.id;
|
||||
if (versionInfo.inheritsFrom != null) {
|
||||
@ -323,9 +328,6 @@ public final class Tools {
|
||||
|
||||
String userType = "mojang";
|
||||
|
||||
File gameDir = new File(strGameDir);
|
||||
gameDir.mkdirs();
|
||||
|
||||
Map<String, String> varArgMap = new ArrayMap<>();
|
||||
varArgMap.put("auth_session", profile.accessToken); // For legacy versions of MC
|
||||
varArgMap.put("auth_access_token", profile.accessToken);
|
||||
@ -341,39 +343,23 @@ public final class Tools {
|
||||
varArgMap.put("version_name", versionName);
|
||||
varArgMap.put("version_type", versionInfo.type);
|
||||
|
||||
List<String> minecraftArgs = new ArrayList<String>();
|
||||
List<String> minecraftArgs = new ArrayList<>();
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
} //TODO: implement else clause
|
||||
}
|
||||
}
|
||||
|
||||
String[] argsFromJson = JSONUtils.insertJSONValueList(
|
||||
return 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) {
|
||||
@ -387,7 +373,7 @@ public final class Tools {
|
||||
}
|
||||
|
||||
private static String[] splitAndFilterEmpty(String argStr) {
|
||||
List<String> strList = new ArrayList<String>();
|
||||
List<String> strList = new ArrayList<>();
|
||||
for (String arg : argStr.split(" ")) {
|
||||
if (!arg.isEmpty()) {
|
||||
strList.add(arg);
|
||||
@ -415,10 +401,11 @@ public final class Tools {
|
||||
private static String getLWJGL3ClassPath() {
|
||||
StringBuilder libStr = new StringBuilder();
|
||||
File lwjgl3Folder = new File(Tools.DIR_GAME_HOME, "lwjgl3");
|
||||
if (/* info.arguments != null && */ lwjgl3Folder.exists()) {
|
||||
for (File file: lwjgl3Folder.listFiles()) {
|
||||
File[] lwjgl3Files = lwjgl3Folder.listFiles();
|
||||
if (lwjgl3Files != null) {
|
||||
for (File file: lwjgl3Files) {
|
||||
if (file.getName().endsWith(".jar")) {
|
||||
libStr.append(file.getAbsolutePath() + ":");
|
||||
libStr.append(file.getAbsolutePath()).append(":");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -427,7 +414,7 @@ public final class Tools {
|
||||
return libStr.toString();
|
||||
}
|
||||
|
||||
private static boolean isClientFirst = false;
|
||||
private final static boolean isClientFirst = false;
|
||||
public static String generateLaunchClassPath(JMinecraftVersionList.Version info,String actualname) {
|
||||
StringBuilder libStr = new StringBuilder(); //versnDir + "/" + version + "/" + version + ".jar:";
|
||||
|
||||
@ -441,7 +428,7 @@ public final class Tools {
|
||||
Log.d(APP_NAME, "Ignored non-exists file: " + perJar);
|
||||
continue;
|
||||
}
|
||||
libStr.append((isClientFirst ? ":" : "") + perJar + (!isClientFirst ? ":" : ""));
|
||||
libStr.append((isClientFirst ? ":" : "")).append(perJar).append(!isClientFirst ? ":" : "");
|
||||
}
|
||||
if (!isClientFirst) {
|
||||
libStr.append(getPatchedFile(actualname));
|
||||
@ -520,8 +507,8 @@ public final class Tools {
|
||||
|
||||
public static void copyAssetFile(Context ctx, String fileName, String output, String outputName, boolean overwrite) throws IOException {
|
||||
File parentFolder = new File(output);
|
||||
if(!parentFolder.exists()) {
|
||||
parentFolder.mkdirs();
|
||||
if(!parentFolder.exists() && !parentFolder.mkdirs()) {
|
||||
throw new IOException("Failed to create parent directory");
|
||||
}
|
||||
File destinationFile = new File(output, outputName);
|
||||
if(!destinationFile.exists() || overwrite){
|
||||
@ -611,32 +598,6 @@ public final class Tools {
|
||||
.show());
|
||||
}
|
||||
|
||||
public static void moveInside(String from, String to) {
|
||||
File fromFile = new File(from);
|
||||
for (File fromInside : fromFile.listFiles()) {
|
||||
moveRecursive(fromInside.getAbsolutePath(), to);
|
||||
}
|
||||
fromFile.delete();
|
||||
}
|
||||
|
||||
public static void moveRecursive(String from, String to) {
|
||||
moveRecursive(new File(from), new File(to));
|
||||
}
|
||||
|
||||
public static void moveRecursive(File from, File to) {
|
||||
File toFrom = new File(to, from.getName());
|
||||
try {
|
||||
if (from.isDirectory()) {
|
||||
for (File child : from.listFiles()) {
|
||||
moveRecursive(child, toFrom);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
from.getParentFile().mkdirs();
|
||||
from.renameTo(toFrom);
|
||||
}
|
||||
}
|
||||
|
||||
public static void openURL(Activity act, String url) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
act.startActivity(browserIntent);
|
||||
@ -652,7 +613,7 @@ public final class Tools {
|
||||
return true; // allow if none match
|
||||
}
|
||||
public static String[] generateLibClasspath(JMinecraftVersionList.Version info) {
|
||||
List<String> libDir = new ArrayList<String>();
|
||||
List<String> libDir = new ArrayList<>();
|
||||
for (DependentLibrary libItem: info.libraries) {
|
||||
if(!checkRules(libItem.rules)) continue;
|
||||
libDir.add(Tools.DIR_HOME_LIBRARY + "/" + Tools.artifactToPath(libItem.name));
|
||||
@ -664,18 +625,14 @@ public final class Tools {
|
||||
return getVersionInfo(versionName, false);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public static JMinecraftVersionList.Version getVersionInfo(String versionName, boolean skipInheriting) {
|
||||
try {
|
||||
JMinecraftVersionList.Version customVer = Tools.GLOBAL_GSON.fromJson(read(DIR_HOME_VERSION + "/" + versionName + "/" + versionName + ".json"), JMinecraftVersionList.Version.class);
|
||||
if (skipInheriting || customVer.inheritsFrom == null || customVer.inheritsFrom.equals(customVer.id)) {
|
||||
return customVer;
|
||||
} else {
|
||||
JMinecraftVersionList.Version inheritsVer = null;
|
||||
/*for (JMinecraftVersionList.Version valueVer : ((JMinecraftVersionList) ExtraCore.getValue(ExtraConstants.RELEASE_TABLE)).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");
|
||||
}
|
||||
}*/
|
||||
JMinecraftVersionList.Version inheritsVer;
|
||||
//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);
|
||||
@ -689,7 +646,7 @@ public final class Tools {
|
||||
"releaseTime", "time", "type"
|
||||
);
|
||||
|
||||
List<DependentLibrary> libList = new ArrayList<DependentLibrary>(Arrays.asList(inheritsVer.libraries));
|
||||
List<DependentLibrary> libList = new ArrayList<>(Arrays.asList(inheritsVer.libraries));
|
||||
try {
|
||||
loop_1:
|
||||
for (DependentLibrary lib : customVer.libraries) {
|
||||
@ -715,8 +672,7 @@ public final class Tools {
|
||||
|
||||
// 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));
|
||||
List totalArgList = new ArrayList(Arrays.asList(inheritsVer.arguments.game));
|
||||
|
||||
int nskip = 0;
|
||||
for (int i = 0; i < customVer.arguments.game.length; i++) {
|
||||
@ -786,7 +742,9 @@ public final class Tools {
|
||||
public static void write(String path, String content) throws IOException {
|
||||
File file = new File(path);
|
||||
File parent = file.getParentFile();
|
||||
if(!parent.exists()) parent.mkdirs();
|
||||
if(parent != null && !parent.exists()) {
|
||||
if(!parent.mkdirs()) throw new IOException("Failed to create parent directory");
|
||||
}
|
||||
try(FileOutputStream outStream = new FileOutputStream(file)) {
|
||||
IOUtils.write(content, outStream);
|
||||
}
|
||||
@ -807,7 +765,7 @@ public final class Tools {
|
||||
try (InputStream is = new FileInputStream(f)) {
|
||||
sha1_dst = new String(Hex.encodeHex(org.apache.commons.codec.digest.DigestUtils.sha1(is)));
|
||||
}
|
||||
if(sha1_dst != null && sourceSHA != null) {
|
||||
if(sourceSHA != null) {
|
||||
return sha1_dst.equalsIgnoreCase(sourceSHA);
|
||||
} else{
|
||||
return true; // fake match
|
||||
|
@ -6,6 +6,7 @@ import android.os.Looper;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.kdt.mcgui.ProgressLayout;
|
||||
@ -26,6 +27,7 @@ import java.net.HttpURLConnection;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
@ -52,7 +54,6 @@ public class MicrosoftBackgroundLogin {
|
||||
}
|
||||
|
||||
/* Fields used to fill the account */
|
||||
public boolean isRefresh;
|
||||
public String msRefreshToken;
|
||||
public String mcName;
|
||||
public String mcToken;
|
||||
@ -60,10 +61,6 @@ public class MicrosoftBackgroundLogin {
|
||||
public boolean doesOwnGame;
|
||||
public long expiresAt;
|
||||
|
||||
public MicrosoftBackgroundLogin(String filename){
|
||||
this(false, MinecraftAccount.load(filename).accessToken);
|
||||
}
|
||||
|
||||
public MicrosoftBackgroundLogin(boolean isRefresh, String authCode){
|
||||
mIsRefresh = isRefresh;
|
||||
mAuthCode = authCode;
|
||||
@ -133,14 +130,14 @@ public class MicrosoftBackgroundLogin {
|
||||
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
|
||||
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||
conn.setRequestProperty("charset", "utf-8");
|
||||
conn.setRequestProperty("Content-Length", Integer.toString(formData.getBytes("UTF-8").length));
|
||||
conn.setRequestProperty("Content-Length", Integer.toString(formData.getBytes(StandardCharsets.UTF_8).length));
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setUseCaches(false);
|
||||
conn.setDoInput(true);
|
||||
conn.setDoOutput(true);
|
||||
conn.connect();
|
||||
try(OutputStream wr = conn.getOutputStream()) {
|
||||
wr.write(formData.getBytes("UTF-8"));
|
||||
wr.write(formData.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
if(conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) {
|
||||
JSONObject jo = new JSONObject(Tools.read(conn.getInputStream()));
|
||||
@ -150,11 +147,8 @@ public class MicrosoftBackgroundLogin {
|
||||
return jo.getString("access_token");
|
||||
//acquireXBLToken(jo.getString("access_token"));
|
||||
}else{
|
||||
throwResponseError(conn);
|
||||
throw getResponseThrowable(conn);
|
||||
}
|
||||
|
||||
// Shouldn't happen
|
||||
return null;
|
||||
}
|
||||
|
||||
private String acquireXBLToken(String accessToken) throws IOException, JSONException {
|
||||
@ -171,11 +165,11 @@ public class MicrosoftBackgroundLogin {
|
||||
|
||||
String req = data.toString();
|
||||
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
|
||||
setCommonProperties(conn, req, true);
|
||||
setCommonProperties(conn, req);
|
||||
conn.connect();
|
||||
|
||||
try(OutputStream wr = conn.getOutputStream()) {
|
||||
wr.write(req.getBytes("UTF-8"));
|
||||
wr.write(req.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
if(conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) {
|
||||
JSONObject jo = new JSONObject(Tools.read(conn.getInputStream()));
|
||||
@ -184,15 +178,12 @@ public class MicrosoftBackgroundLogin {
|
||||
return jo.getString("Token");
|
||||
//acquireXsts(jo.getString("Token"));
|
||||
}else{
|
||||
throwResponseError(conn);
|
||||
throw getResponseThrowable(conn);
|
||||
}
|
||||
|
||||
// Shouldn't happen
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @return [uhs, token]*/
|
||||
private String[] acquireXsts(String xblToken) throws IOException, JSONException {
|
||||
private @NonNull String[] acquireXsts(String xblToken) throws IOException, JSONException {
|
||||
URL url = new URL(xstsAuthUrl);
|
||||
|
||||
JSONObject data = new JSONObject();
|
||||
@ -206,12 +197,12 @@ public class MicrosoftBackgroundLogin {
|
||||
String req = data.toString();
|
||||
Log.i("MicroAuth", req);
|
||||
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
|
||||
setCommonProperties(conn, req, true);
|
||||
setCommonProperties(conn, req);
|
||||
Log.i("MicroAuth", conn.getRequestMethod());
|
||||
conn.connect();
|
||||
|
||||
try(OutputStream wr = conn.getOutputStream()) {
|
||||
wr.write(req.getBytes("UTF-8"));
|
||||
wr.write(req.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
if(conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) {
|
||||
@ -232,10 +223,8 @@ public class MicrosoftBackgroundLogin {
|
||||
}
|
||||
throw new PresentedException(new RuntimeException(responseContents), R.string.xerr_unknown, xerr);
|
||||
}else{
|
||||
throwResponseError(conn);
|
||||
throw getResponseThrowable(conn);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String acquireMinecraftToken(String xblUhs, String xblXsts) throws IOException, JSONException {
|
||||
@ -246,11 +235,11 @@ public class MicrosoftBackgroundLogin {
|
||||
|
||||
String req = data.toString();
|
||||
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
|
||||
setCommonProperties(conn, req, true);
|
||||
setCommonProperties(conn, req);
|
||||
conn.connect();
|
||||
|
||||
try(OutputStream wr = conn.getOutputStream()) {
|
||||
wr.write(req.getBytes("UTF-8"));
|
||||
wr.write(req.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
if(conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) {
|
||||
@ -262,10 +251,8 @@ public class MicrosoftBackgroundLogin {
|
||||
//checkMcProfile(jo.getString("access_token"));
|
||||
return jo.getString("access_token");
|
||||
}else{
|
||||
throwResponseError(conn);
|
||||
throw getResponseThrowable(conn);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void checkMcProfile(String mcAccessToken) throws IOException, JSONException {
|
||||
@ -308,20 +295,20 @@ public class MicrosoftBackgroundLogin {
|
||||
}
|
||||
|
||||
|
||||
/** Set common properties, and enable interactivity if desired */
|
||||
private static void setCommonProperties(HttpURLConnection conn, String formData, boolean interactive) {
|
||||
/** Set common properties for the connection. Given that all requests are POST, interactivity is always enabled */
|
||||
private static void setCommonProperties(HttpURLConnection conn, String formData) {
|
||||
conn.setRequestProperty("Content-Type", "application/json");
|
||||
conn.setRequestProperty("Accept", "application/json");
|
||||
conn.setRequestProperty("charset", "utf-8");
|
||||
try {
|
||||
conn.setRequestProperty("Content-Length", Integer.toString(formData.getBytes("UTF-8").length));
|
||||
conn.setRequestProperty("Content-Length", Integer.toString(formData.getBytes(StandardCharsets.UTF_8).length));
|
||||
conn.setRequestMethod("POST");
|
||||
}catch (ProtocolException | UnsupportedEncodingException e) {
|
||||
}catch (ProtocolException e) {
|
||||
Log.e("MicrosoftAuth", e.toString());
|
||||
}
|
||||
conn.setUseCaches(false);
|
||||
conn.setDoInput(true);
|
||||
conn.setDoOutput(interactive);
|
||||
conn.setDoOutput(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -339,11 +326,11 @@ public class MicrosoftBackgroundLogin {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private void throwResponseError(HttpURLConnection conn) throws IOException {
|
||||
private RuntimeException getResponseThrowable(HttpURLConnection conn) throws IOException {
|
||||
Log.i("MicrosoftLogin", "Error code: " + conn.getResponseCode() + ": " + conn.getResponseMessage());
|
||||
if(conn.getResponseCode() == 429) {
|
||||
throw new PresentedException(R.string.microsoft_login_retry_later);
|
||||
return new PresentedException(R.string.microsoft_login_retry_later);
|
||||
}
|
||||
throw new RuntimeException(conn.getResponseMessage());
|
||||
return new RuntimeException(conn.getResponseMessage());
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
package net.kdt.pojavlaunch.authenticator.microsoft;
|
||||
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
|
||||
/**
|
||||
* Simple class which tries to handle all irrecoverable failures when logging in a Microsoft account.
|
||||
*/
|
||||
public class MicrosoftLoginFailHandler {
|
||||
|
||||
|
||||
/** Evaluate which error message to display, else */
|
||||
public static String getErrorMessage(){
|
||||
// TODO handle this for real though
|
||||
return "ERROR";
|
||||
}
|
||||
|
||||
}
|
@ -9,7 +9,6 @@ import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.kdt.pojavlaunch.colorselector;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Color;
|
||||
@ -12,7 +11,6 @@ import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
|
||||
|
@ -1,23 +1,25 @@
|
||||
package net.kdt.pojavlaunch.customcontrols;
|
||||
|
||||
import android.util.*;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||
import net.kdt.pojavlaunch.utils.*;
|
||||
import net.objecthunter.exp4j.*;
|
||||
import net.objecthunter.exp4j.function.Function;
|
||||
|
||||
import org.lwjgl.glfw.*;
|
||||
|
||||
import static net.kdt.pojavlaunch.LwjglGlfwKeycode.GLFW_KEY_UNKNOWN;
|
||||
import static org.lwjgl.glfw.CallbackBridge.sendKeyPress;
|
||||
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||
import net.kdt.pojavlaunch.utils.JSONUtils;
|
||||
import net.objecthunter.exp4j.ExpressionBuilder;
|
||||
import net.objecthunter.exp4j.function.Function;
|
||||
|
||||
import org.lwjgl.glfw.CallbackBridge;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Keep
|
||||
public class ControlData {
|
||||
|
||||
@ -76,7 +78,7 @@ public class ControlData {
|
||||
|
||||
public static List<String> buildSpecialButtonArray() {
|
||||
if (SPECIAL_BUTTON_NAME_ARRAY == null) {
|
||||
List<String> nameList = new ArrayList<String>();
|
||||
List<String> nameList = new ArrayList<>();
|
||||
for (ControlData btn : getSpecialButtons()) {
|
||||
nameList.add("SPECIAL_" + btn.name);
|
||||
}
|
||||
@ -107,7 +109,7 @@ public class ControlData {
|
||||
}
|
||||
|
||||
public ControlData(String name, int[] keycodes) {
|
||||
this(name, keycodes, Tools.currentDisplayMetrics.widthPixels/2, Tools.currentDisplayMetrics.heightPixels/2);
|
||||
this(name, keycodes, Tools.currentDisplayMetrics.widthPixels/2f, Tools.currentDisplayMetrics.heightPixels/2f);
|
||||
}
|
||||
|
||||
public ControlData(String name, int[] keycodes, float x, float y) {
|
||||
@ -176,12 +178,6 @@ public class ControlData {
|
||||
controlData.cornerRadius
|
||||
);
|
||||
}
|
||||
|
||||
public void execute(boolean isDown) {
|
||||
for(int keycode : keycodes){
|
||||
sendKeyPress(keycode, 0, isDown);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public float insertDynamicPos(String dynamicPos) {
|
||||
@ -204,6 +200,7 @@ public class ControlData {
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
public boolean containsKeycode(int keycodeToCheck){
|
||||
for(int keycode : keycodes)
|
||||
if(keycodeToCheck == keycode)
|
||||
|
@ -10,13 +10,11 @@ import static net.kdt.pojavlaunch.customcontrols.ControlDrawerData.Orientation.R
|
||||
import static net.kdt.pojavlaunch.customcontrols.ControlDrawerData.Orientation.UP;
|
||||
import static net.kdt.pojavlaunch.customcontrols.ControlDrawerData.Orientation.FREE;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
@androidx.annotation.Keep
|
||||
public class ControlDrawerData {
|
||||
|
||||
public ArrayList<ControlData> buttonProperties;
|
||||
public ControlData properties;
|
||||
public final ArrayList<ControlData> buttonProperties;
|
||||
public final ControlData properties;
|
||||
public Orientation orientation;
|
||||
|
||||
@androidx.annotation.Keep
|
||||
@ -59,7 +57,7 @@ public class ControlDrawerData {
|
||||
}
|
||||
|
||||
public ControlDrawerData(ArrayList<ControlData> buttonProperties){
|
||||
this(buttonProperties, new ControlData("Drawer", new int[] {}, Tools.currentDisplayMetrics.widthPixels/2, Tools.currentDisplayMetrics.heightPixels/2));
|
||||
this(buttonProperties, new ControlData("Drawer", new int[] {}, Tools.currentDisplayMetrics.widthPixels/2f, Tools.currentDisplayMetrics.heightPixels/2f));
|
||||
}
|
||||
|
||||
public ControlDrawerData(ArrayList<ControlData> buttonProperties, ControlData properties){
|
||||
|
@ -2,6 +2,7 @@ package net.kdt.pojavlaunch.customcontrols;
|
||||
import static android.content.Context.INPUT_METHOD_SERVICE;
|
||||
import static net.kdt.pojavlaunch.Tools.currentDisplayMetrics;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.*;
|
||||
import android.util.*;
|
||||
import android.view.*;
|
||||
@ -213,12 +214,9 @@ public class ControlLayout extends FrameLayout {
|
||||
}
|
||||
|
||||
public void setModifiable(boolean isModifiable) {
|
||||
if(isModifiable){
|
||||
}else {
|
||||
if(mModifiable)
|
||||
removeEditWindow();
|
||||
if(!isModifiable && mModifiable){
|
||||
removeEditWindow();
|
||||
}
|
||||
|
||||
mModifiable = isModifiable;
|
||||
}
|
||||
|
||||
@ -298,20 +296,20 @@ public class ControlLayout extends FrameLayout {
|
||||
}
|
||||
|
||||
|
||||
HashMap<View, ControlInterface> mapTable = new HashMap<>();
|
||||
int[] location = new int[2];
|
||||
final HashMap<View, ControlInterface> mapTable = new HashMap<>();
|
||||
final int[] location = new int[2];
|
||||
//While this is called onTouch, this should only be called from a ControlButton.
|
||||
public boolean onTouch(View v, MotionEvent ev) {
|
||||
public void onTouch(View v, MotionEvent ev) {
|
||||
ControlInterface lastControlButton = mapTable.get(v);
|
||||
|
||||
//Check if the action is cancelling, reset the lastControl button associated to the view
|
||||
if(ev.getActionMasked() == MotionEvent.ACTION_UP || ev.getActionMasked() == MotionEvent.ACTION_CANCEL){
|
||||
if(lastControlButton != null) lastControlButton.sendKeyPresses(false);
|
||||
mapTable.put(v, null);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(ev.getActionMasked() != MotionEvent.ACTION_MOVE) return false;
|
||||
if(ev.getActionMasked() != MotionEvent.ACTION_MOVE) return;
|
||||
|
||||
getLocationOnScreen(location);
|
||||
|
||||
@ -321,7 +319,7 @@ public class ControlLayout extends FrameLayout {
|
||||
&& ev.getRawX() < lastControlButton.getControlView().getX() + lastControlButton.getControlView().getWidth() + location[0]
|
||||
&& ev.getRawY() > lastControlButton.getControlView().getY()
|
||||
&& ev.getRawY() < lastControlButton.getControlView().getY() + lastControlButton.getControlView().getHeight()){
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -342,14 +340,14 @@ public class ControlLayout extends FrameLayout {
|
||||
if(!button.equals(lastControlButton)){
|
||||
button.sendKeyPresses(true);
|
||||
mapTable.put(v, button);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (mModifiable && event.getActionMasked() != MotionEvent.ACTION_UP || mControlPopup == null)
|
||||
|
@ -47,7 +47,7 @@ public class CustomControls {
|
||||
this.mControlDataList.add(new ControlData(ctx, R.string.control_inventory, new int[]{LwjglGlfwKeycode.GLFW_KEY_E}, "${margin} * 3 + ${width} * 2", "${bottom} - ${margin}", true));
|
||||
|
||||
ControlData shiftData = new ControlData(ctx, R.string.control_shift, new int[]{LwjglGlfwKeycode.GLFW_KEY_LEFT_SHIFT}, "${margin} * 2 + ${width}", "${screen_height} - ${margin} * 2 - ${height} * 2", true);
|
||||
shiftData.isToggle = true;
|
||||
shiftData.isToggle = true;
|
||||
this.mControlDataList.add(shiftData);
|
||||
this.mControlDataList.add(new ControlData(ctx, R.string.control_jump, new int[]{LwjglGlfwKeycode.GLFW_KEY_SPACE}, "${right} - ${margin} * 2 - ${width}", "${bottom} - ${margin} * 2 - ${height}", true));
|
||||
|
||||
|
@ -14,7 +14,6 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class LayoutConverter {
|
||||
public static boolean convertLookType = false; //false = flat; true = classic
|
||||
public static CustomControls loadAndConvertIfNecessary(String jsonPath) throws IOException, JsonSyntaxException {
|
||||
|
||||
String jsonLayoutData = Tools.read(jsonPath);
|
||||
@ -107,14 +106,8 @@ public class LayoutConverter {
|
||||
n_button.isToggle = button.getBoolean("isToggle");
|
||||
n_button.setHeight(button.getInt("height"));
|
||||
n_button.setWidth(button.getInt("width"));
|
||||
if(convertLookType) {
|
||||
n_button.strokeColor = 0xdd7f7f7f;
|
||||
n_button.bgColor = 0x807f7f7f;
|
||||
n_button.strokeWidth = 10;
|
||||
}else{
|
||||
n_button.bgColor = 0x4d000000;
|
||||
n_button.strokeWidth = 0;
|
||||
}
|
||||
n_button.bgColor = 0x4d000000;
|
||||
n_button.strokeWidth = 0;
|
||||
if(button.getBoolean("isRound")) { n_button.cornerRadius = 35f; }
|
||||
int next_idx = 0;
|
||||
if(button.getBoolean("holdShift")) { keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_SHIFT; next_idx++; }
|
||||
|
@ -1,25 +1,30 @@
|
||||
package net.kdt.pojavlaunch.customcontrols.buttons;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.*;
|
||||
import android.util.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
|
||||
|
||||
import net.kdt.pojavlaunch.customcontrols.ControlButtonMenuListener;
|
||||
import net.kdt.pojavlaunch.customcontrols.ControlData;
|
||||
import net.kdt.pojavlaunch.customcontrols.ControlLayout;
|
||||
import net.kdt.pojavlaunch.customcontrols.handleview.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||
|
||||
import org.lwjgl.glfw.*;
|
||||
|
||||
import static net.kdt.pojavlaunch.LwjglGlfwKeycode.GLFW_KEY_UNKNOWN;
|
||||
import static org.lwjgl.glfw.CallbackBridge.sendKeyPress;
|
||||
import static org.lwjgl.glfw.CallbackBridge.sendMouseButton;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.kdt.pojavlaunch.LwjglGlfwKeycode;
|
||||
import net.kdt.pojavlaunch.MainActivity;
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.customcontrols.ControlData;
|
||||
import net.kdt.pojavlaunch.customcontrols.ControlLayout;
|
||||
import net.kdt.pojavlaunch.customcontrols.handleview.EditControlPopup;
|
||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||
|
||||
import org.lwjgl.glfw.CallbackBridge;
|
||||
|
||||
@SuppressLint({"ViewConstructor", "AppCompatCustomView"})
|
||||
public class ControlButton extends TextView implements ControlInterface {
|
||||
private final Paint mRectPaint = new Paint();
|
||||
@ -103,6 +108,7 @@ public class ControlButton extends TextView implements ControlInterface {
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
switch (event.getActionMasked()){
|
||||
@ -169,6 +175,7 @@ public class ControlButton extends TextView implements ControlInterface {
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
public boolean triggerToggle(){
|
||||
//returns true a the toggle system is triggered
|
||||
if(mProperties.isToggle){
|
||||
|
@ -2,7 +2,6 @@ package net.kdt.pojavlaunch.customcontrols.buttons;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
@ -19,9 +18,9 @@ import java.util.ArrayList;
|
||||
public class ControlDrawer extends ControlButton {
|
||||
|
||||
|
||||
public ArrayList<ControlSubButton> buttons;
|
||||
public ControlDrawerData drawerData;
|
||||
public ControlLayout parentLayout;
|
||||
public final ArrayList<ControlSubButton> buttons;
|
||||
public final ControlDrawerData drawerData;
|
||||
public final ControlLayout parentLayout;
|
||||
public boolean areButtonsVisible;
|
||||
|
||||
|
||||
@ -164,9 +163,9 @@ public class ControlDrawer extends ControlButton {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSnap(ControlInterface button) {
|
||||
boolean result = super.canSnap(button);
|
||||
return result && !containsChild(button);
|
||||
public boolean cantSnap(ControlInterface button) {
|
||||
boolean result = !super.cantSnap(button);
|
||||
return !result || containsChild(button);
|
||||
}
|
||||
|
||||
//Getters
|
||||
|
@ -2,9 +2,8 @@ package net.kdt.pojavlaunch.customcontrols.buttons;
|
||||
|
||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_BUTTONSIZE;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.util.TypedValue;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -13,8 +12,6 @@ import android.widget.FrameLayout;
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.core.math.MathUtils;
|
||||
|
||||
import net.kdt.pojavlaunch.MinecraftGLSurface;
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
import net.kdt.pojavlaunch.customcontrols.ControlData;
|
||||
import net.kdt.pojavlaunch.customcontrols.ControlLayout;
|
||||
@ -182,24 +179,22 @@ public interface ControlInterface extends View.OnLongClickListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Passe a series of checks to determine if the ControlButton is available to be snapped on.
|
||||
* Passe a series of checks to determine if the ControlButton isn't available to be snapped on.
|
||||
*
|
||||
* @param button The button to check
|
||||
* @return whether or not the button
|
||||
*/
|
||||
default boolean canSnap(ControlInterface button){
|
||||
default boolean cantSnap(ControlInterface button){
|
||||
float MIN_DISTANCE = Tools.dpToPx(8);
|
||||
|
||||
if(button == this) return false;
|
||||
if(net.kdt.pojavlaunch.utils.MathUtils.dist(
|
||||
button.getControlView().getX() + button.getControlView().getWidth()/2f,
|
||||
button.getControlView().getY() + button.getControlView().getHeight()/2f,
|
||||
getControlView().getX() + getControlView().getWidth()/2f,
|
||||
getControlView().getY() + getControlView().getHeight()/2f)
|
||||
> Math.max(button.getControlView().getWidth()/2f + getControlView().getWidth()/2f,
|
||||
button.getControlView().getHeight()/2f + getControlView().getHeight()/2f) + MIN_DISTANCE) return false;
|
||||
|
||||
return true;
|
||||
if(button == this) return true;
|
||||
return net.kdt.pojavlaunch.utils.MathUtils.dist(
|
||||
button.getControlView().getX() + button.getControlView().getWidth() / 2f,
|
||||
button.getControlView().getY() + button.getControlView().getHeight() / 2f,
|
||||
getControlView().getX() + getControlView().getWidth() / 2f,
|
||||
getControlView().getY() + getControlView().getHeight() / 2f)
|
||||
> Math.max(button.getControlView().getWidth() / 2f + getControlView().getWidth() / 2f,
|
||||
button.getControlView().getHeight() / 2f + getControlView().getHeight() / 2f) + MIN_DISTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -222,7 +217,7 @@ public interface ControlInterface extends View.OnLongClickListener {
|
||||
|
||||
for(ControlInterface button : ((ControlLayout) getControlView().getParent()).getButtonChildren()){
|
||||
//Step 1: Filter unwanted buttons
|
||||
if(!canSnap(button)) continue;
|
||||
if(cantSnap(button)) continue;
|
||||
|
||||
//Step 2: Get Coordinates
|
||||
float button_top = button.getControlView().getY();
|
||||
@ -282,11 +277,11 @@ public interface ControlInterface extends View.OnLongClickListener {
|
||||
/** Inject a touch listener on the view to make editing controls straight forward */
|
||||
default void injectTouchEventBehavior(){
|
||||
getControlView().setOnTouchListener(new View.OnTouchListener() {
|
||||
private boolean mIsPointerOutOfBounds = false;
|
||||
private boolean mCanTriggerLongClick = true;
|
||||
private float downX, downY;
|
||||
private float downRawX, downRawY;
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent event) {
|
||||
if(!getControlLayoutParent().getModifiable()){
|
||||
|
@ -1,12 +1,10 @@
|
||||
package net.kdt.pojavlaunch.customcontrols.buttons;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import net.kdt.pojavlaunch.SingleTapConfirm;
|
||||
import net.kdt.pojavlaunch.customcontrols.ControlData;
|
||||
import net.kdt.pojavlaunch.customcontrols.ControlDrawerData;
|
||||
import net.kdt.pojavlaunch.customcontrols.ControlLayout;
|
||||
@ -14,7 +12,7 @@ import net.kdt.pojavlaunch.customcontrols.ControlLayout;
|
||||
@SuppressLint("ViewConstructor")
|
||||
public class ControlSubButton extends ControlButton {
|
||||
|
||||
public ControlDrawer parentDrawer;
|
||||
public final ControlDrawer parentDrawer;
|
||||
|
||||
public ControlSubButton(ControlLayout layout, ControlData properties, ControlDrawer parentDrawer) {
|
||||
super(layout, properties);
|
||||
@ -44,6 +42,7 @@ public class ControlSubButton extends ControlButton {
|
||||
super.setLayoutParams(params);
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if(!getControlLayoutParent().getModifiable() || parentDrawer.drawerData.orientation == ControlDrawerData.Orientation.FREE){
|
||||
|
@ -58,7 +58,7 @@ public class Gamepad implements GrabListener {
|
||||
private float mLastHorizontalValue = 0.0f;
|
||||
private float mLastVerticalValue = 0.0f;
|
||||
|
||||
private final double MOUSE_MAX_ACCELERATION = 2f;
|
||||
private static final double MOUSE_MAX_ACCELERATION = 2f;
|
||||
|
||||
private double mMouseMagnitude;
|
||||
private double mMouseAngle;
|
||||
@ -79,7 +79,8 @@ public class Gamepad implements GrabListener {
|
||||
private long mLastFrameTime;
|
||||
|
||||
/* Listen for change in gui scale */
|
||||
private MCOptionUtils.MCOptionListener mGuiScaleListener = () -> notifyGUISizeChange(getMcScale());
|
||||
@SuppressWarnings("FieldCanBeLocal") //the field is used in a WeakReference
|
||||
private final MCOptionUtils.MCOptionListener mGuiScaleListener = () -> notifyGUISizeChange(getMcScale());
|
||||
|
||||
public Gamepad(View contextView, InputDevice inputDevice){
|
||||
mScreenChoreographer = Choreographer.getInstance();
|
||||
@ -124,8 +125,8 @@ public class Gamepad implements GrabListener {
|
||||
int size = (int) ((22 * getMcScale()) / mScaleFactor);
|
||||
mPointerImageView.setLayoutParams(new FrameLayout.LayoutParams(size, size));
|
||||
|
||||
mMouse_x = CallbackBridge.windowWidth/2;
|
||||
mMouse_y = CallbackBridge.windowHeight/2;
|
||||
mMouse_x = CallbackBridge.windowWidth/2f;
|
||||
mMouse_y = CallbackBridge.windowHeight/2f;
|
||||
CallbackBridge.sendCursorPos(mMouse_x, mMouse_y);
|
||||
placePointerView(CallbackBridge.physicalWidth/2, CallbackBridge.physicalHeight/2);
|
||||
|
||||
@ -418,8 +419,8 @@ public class Gamepad implements GrabListener {
|
||||
}
|
||||
|
||||
private void placePointerView(int x, int y){
|
||||
mPointerImageView.setX(x - mPointerImageView.getWidth()/2);
|
||||
mPointerImageView.setY(y - mPointerImageView.getHeight()/2);
|
||||
mPointerImageView.setX(x - mPointerImageView.getWidth()/2f);
|
||||
mPointerImageView.setY(y - mPointerImageView.getHeight()/2f);
|
||||
}
|
||||
|
||||
/** Update the grabbing state, and change the currentMap, mouse position and sensibility */
|
||||
@ -441,8 +442,8 @@ public class Gamepad implements GrabListener {
|
||||
mCurrentMap = mMenuMap;
|
||||
sendDirectionalKeycode(mCurrentJoystickDirection, false, mGameMap); // removing what we were doing
|
||||
|
||||
mMouse_x = CallbackBridge.windowWidth/2;
|
||||
mMouse_y = CallbackBridge.windowHeight/2;
|
||||
mMouse_x = CallbackBridge.windowWidth/2f;
|
||||
mMouse_y = CallbackBridge.windowHeight/2f;
|
||||
CallbackBridge.sendCursorPos(mMouse_x, mMouse_y);
|
||||
placePointerView(CallbackBridge.physicalWidth/2, CallbackBridge.physicalHeight/2);
|
||||
mPointerImageView.setVisibility(View.VISIBLE);
|
||||
|
@ -1,11 +1,6 @@
|
||||
package net.kdt.pojavlaunch.customcontrols.gamepad;
|
||||
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import static android.view.InputDevice.KEYBOARD_TYPE_ALPHABETIC;
|
||||
import static android.view.InputDevice.KEYBOARD_TYPE_NON_ALPHABETIC;
|
||||
import static android.view.InputDevice.SOURCE_GAMEPAD;
|
||||
import static android.view.KeyEvent.KEYCODE_DPAD_CENTER;
|
||||
import static android.view.KeyEvent.KEYCODE_DPAD_DOWN;
|
||||
@ -13,6 +8,10 @@ import static android.view.KeyEvent.KEYCODE_DPAD_LEFT;
|
||||
import static android.view.KeyEvent.KEYCODE_DPAD_RIGHT;
|
||||
import static android.view.KeyEvent.KEYCODE_DPAD_UP;
|
||||
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
|
||||
public class GamepadDpad {
|
||||
private int mLastKeycode = KEYCODE_DPAD_CENTER;
|
||||
@ -50,7 +49,7 @@ public class GamepadDpad {
|
||||
|
||||
}
|
||||
|
||||
public static boolean isDpadEvent(MotionEvent event) {
|
||||
@SuppressWarnings("unused") public static boolean isDpadEvent(MotionEvent event) {
|
||||
// Check that input comes from a device with directional pads.
|
||||
// And... also the joystick since it declares sometimes as a joystick.
|
||||
return (event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK;
|
||||
|
@ -14,32 +14,32 @@ public class GamepadMap {
|
||||
Be warned, you should define ALL keys if you want to avoid a non defined exception
|
||||
*/
|
||||
|
||||
public GamepadButton BUTTON_A = new GamepadButton();
|
||||
public GamepadButton BUTTON_B = new GamepadButton();
|
||||
public GamepadButton BUTTON_X = new GamepadButton();
|
||||
public GamepadButton BUTTON_Y = new GamepadButton();
|
||||
public final GamepadButton BUTTON_A = new GamepadButton();
|
||||
public final GamepadButton BUTTON_B = new GamepadButton();
|
||||
public final GamepadButton BUTTON_X = new GamepadButton();
|
||||
public final GamepadButton BUTTON_Y = new GamepadButton();
|
||||
|
||||
public GamepadButton BUTTON_START = new GamepadButton();
|
||||
public GamepadButton BUTTON_SELECT = new GamepadButton();
|
||||
public final GamepadButton BUTTON_START = new GamepadButton();
|
||||
public final GamepadButton BUTTON_SELECT = new GamepadButton();
|
||||
|
||||
public GamepadButton TRIGGER_RIGHT = new GamepadButton(); //R2
|
||||
public GamepadButton TRIGGER_LEFT = new GamepadButton(); //L2
|
||||
public final GamepadButton TRIGGER_RIGHT = new GamepadButton(); //R2
|
||||
public final GamepadButton TRIGGER_LEFT = new GamepadButton(); //L2
|
||||
|
||||
public GamepadButton SHOULDER_RIGHT = new GamepadButton(); //R1
|
||||
public GamepadButton SHOULDER_LEFT = new GamepadButton(); //L1
|
||||
public final GamepadButton SHOULDER_RIGHT = new GamepadButton(); //R1
|
||||
public final GamepadButton SHOULDER_LEFT = new GamepadButton(); //L1
|
||||
|
||||
public int[] DIRECTION_FORWARD;
|
||||
public int[] DIRECTION_BACKWARD;
|
||||
public int[] DIRECTION_RIGHT;
|
||||
public int[] DIRECTION_LEFT;
|
||||
|
||||
public GamepadButton THUMBSTICK_RIGHT = new GamepadButton(); //R3
|
||||
public GamepadButton THUMBSTICK_LEFT = new GamepadButton(); //L3
|
||||
public final GamepadButton THUMBSTICK_RIGHT = new GamepadButton(); //R3
|
||||
public final GamepadButton THUMBSTICK_LEFT = new GamepadButton(); //L3
|
||||
|
||||
public GamepadButton DPAD_UP = new GamepadButton();
|
||||
public GamepadButton DPAD_RIGHT = new GamepadButton();
|
||||
public GamepadButton DPAD_DOWN = new GamepadButton();
|
||||
public GamepadButton DPAD_LEFT = new GamepadButton();
|
||||
public final GamepadButton DPAD_UP = new GamepadButton();
|
||||
public final GamepadButton DPAD_RIGHT = new GamepadButton();
|
||||
public final GamepadButton DPAD_DOWN = new GamepadButton();
|
||||
public final GamepadButton DPAD_LEFT = new GamepadButton();
|
||||
|
||||
|
||||
/*
|
||||
@ -158,7 +158,7 @@ public class GamepadMap {
|
||||
/*
|
||||
* Returns an pre-initialized GamepadMap with only empty keycodes
|
||||
*/
|
||||
public static GamepadMap getEmptyMap(){
|
||||
@SuppressWarnings("unused") public static GamepadMap getEmptyMap(){
|
||||
GamepadMap emptyMap = new GamepadMap();
|
||||
for(GamepadButton button : emptyMap.getButtons())
|
||||
button.keycodes = new int[]{};
|
||||
|
@ -7,14 +7,12 @@ import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.math.MathUtils;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
import net.kdt.pojavlaunch.customcontrols.buttons.ControlInterface;
|
||||
|
||||
/**
|
||||
@ -22,11 +20,11 @@ import net.kdt.pojavlaunch.customcontrols.buttons.ControlInterface;
|
||||
*/
|
||||
public class ActionRow extends LinearLayout {
|
||||
|
||||
public static int SIDE_LEFT = 0x0;
|
||||
public static int SIDE_TOP = 0x1;
|
||||
public static int SIDE_RIGHT = 0x2;
|
||||
public static int SIDE_BOTTOM = 0x3;
|
||||
public static int SIDE_AUTO = 0x4;
|
||||
public static final int SIDE_LEFT = 0x0;
|
||||
public static final int SIDE_TOP = 0x1;
|
||||
public static final int SIDE_RIGHT = 0x2;
|
||||
public static final int SIDE_BOTTOM = 0x3;
|
||||
public static final int SIDE_AUTO = 0x4;
|
||||
|
||||
public ActionRow(Context context) {
|
||||
super(context); init();
|
||||
@ -49,7 +47,7 @@ public class ActionRow extends LinearLayout {
|
||||
};
|
||||
private final ActionButtonInterface[] actionButtons = new ActionButtonInterface[3];
|
||||
private View mFollowedView = null;
|
||||
private int mSide = SIDE_TOP;
|
||||
private final int mSide = SIDE_TOP;
|
||||
|
||||
/** Add action buttons and configure them */
|
||||
private void init(){
|
||||
@ -130,9 +128,9 @@ public class ActionRow extends LinearLayout {
|
||||
: SIDE_RIGHT;
|
||||
|
||||
float futurePos = getYPosition(side);
|
||||
if(futurePos + getHeight() > (parent.getHeight() + getHeight()/2)){
|
||||
if(futurePos + getHeight() > (parent.getHeight() + getHeight()/2f)){
|
||||
side = SIDE_TOP;
|
||||
}else if (futurePos < -getHeight()/2){
|
||||
}else if (futurePos < -getHeight()/2f){
|
||||
side = SIDE_BOTTOM;
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,7 @@ package net.kdt.pojavlaunch.customcontrols.handleview;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -2,17 +2,12 @@ package net.kdt.pojavlaunch.customcontrols.handleview;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.customcontrols.ControlLayout;
|
||||
import net.kdt.pojavlaunch.customcontrols.buttons.ControlButton;
|
||||
import net.kdt.pojavlaunch.customcontrols.buttons.ControlInterface;
|
||||
|
||||
@SuppressLint("AppCompatCustomView")
|
||||
|
@ -1,11 +1,9 @@
|
||||
package net.kdt.pojavlaunch.customcontrols.handleview;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.DragEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -15,7 +13,6 @@ import androidx.annotation.Nullable;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.customcontrols.buttons.ControlButton;
|
||||
import net.kdt.pojavlaunch.customcontrols.buttons.ControlInterface;
|
||||
|
||||
public class ControlHandleView extends View {
|
||||
@ -66,6 +63,7 @@ public class ControlHandleView extends View {
|
||||
setY(controlInterface.getControlView().getY() + controlInterface.getControlView().getHeight());
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
switch (event.getActionMasked()){
|
||||
|
@ -2,16 +2,12 @@ package net.kdt.pojavlaunch.customcontrols.handleview;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.customcontrols.buttons.ControlButton;
|
||||
import net.kdt.pojavlaunch.customcontrols.buttons.ControlInterface;
|
||||
|
||||
@SuppressLint("AppCompatCustomView")
|
||||
|
@ -4,7 +4,6 @@ import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.VectorDrawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
@ -31,9 +30,9 @@ public class DrawerPullButton extends View {
|
||||
canvas.drawArc(0,-getHeight(),getWidth(), getHeight(), 0, 180, true, mPaint);
|
||||
|
||||
mPaint.setColor(Color.WHITE);
|
||||
mDrawable.setBounds(0, 0, canvas.getHeight(), canvas.getHeight());
|
||||
mDrawable.setBounds(0, 0, getHeight(), getHeight());
|
||||
canvas.save();
|
||||
canvas.translate((canvas.getWidth()-canvas.getHeight())/2, 0);
|
||||
canvas.translate((getWidth()-getHeight())/2f, 0);
|
||||
mDrawable.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
@ -32,16 +31,12 @@ import com.kdt.DefocusableScrollView;
|
||||
|
||||
import net.kdt.pojavlaunch.EfficientAndroidLWJGLKeycode;
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.colorselector.ColorSelectionListener;
|
||||
import net.kdt.pojavlaunch.colorselector.ColorSelector;
|
||||
import net.kdt.pojavlaunch.customcontrols.ControlData;
|
||||
import net.kdt.pojavlaunch.customcontrols.ControlDrawerData;
|
||||
import net.kdt.pojavlaunch.customcontrols.buttons.ControlButton;
|
||||
import net.kdt.pojavlaunch.customcontrols.buttons.ControlDrawer;
|
||||
import net.kdt.pojavlaunch.customcontrols.buttons.ControlInterface;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -83,7 +78,7 @@ public class EditControlPopup {
|
||||
@SuppressLint("UseSwitchCompatOrMaterialCode")
|
||||
protected Switch mToggleSwitch, mPassthroughSwitch, mSwipeableSwitch;
|
||||
protected Spinner mOrientationSpinner;
|
||||
protected Spinner[] mKeycodeSpinners = new Spinner[4];
|
||||
protected final Spinner[] mKeycodeSpinners = new Spinner[4];
|
||||
protected SeekBar mStrokeWidthSeekbar, mCornerRadiusSeekbar, mAlphaSeekbar;
|
||||
protected TextView mStrokePercentTextView, mCornerRadiusPercentTextView, mAlphaPercentTextView;
|
||||
protected TextView mSelectBackgroundColor, mSelectStrokeColor;
|
||||
@ -247,7 +242,7 @@ public class EditControlPopup {
|
||||
|
||||
|
||||
public static void setPercentageText(TextView textView, int progress){
|
||||
textView.setText(progress + " %");
|
||||
textView.setText(textView.getContext().getString(R.string.percent_format, progress));
|
||||
}
|
||||
|
||||
/* LOADING VALUES */
|
||||
@ -305,7 +300,7 @@ public class EditControlPopup {
|
||||
}
|
||||
|
||||
/** Load values for the joystick */
|
||||
public void loadJoystickValues(ControlData data){
|
||||
@SuppressWarnings("unused") public void loadJoystickValues(ControlData data){
|
||||
loadValues(data);
|
||||
|
||||
mMappingTextView.setVisibility(GONE);
|
||||
|
@ -3,11 +3,8 @@ package net.kdt.pojavlaunch.customcontrols.keyboard;
|
||||
|
||||
import static android.content.Context.INPUT_METHOD_SERVICE;
|
||||
|
||||
import static org.lwjgl.glfw.CallbackBridge.sendKeyPress;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
@ -15,15 +12,13 @@ import android.view.inputmethod.InputMethodManager;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.kdt.pojavlaunch.LwjglGlfwKeycode;
|
||||
import net.kdt.pojavlaunch.R;
|
||||
|
||||
import org.lwjgl.glfw.CallbackBridge;
|
||||
|
||||
/**
|
||||
* This class is intended for sending characters used in chat via the virtual keyboard
|
||||
*/
|
||||
public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText {
|
||||
public static final String TEXT_FILLER = " ";
|
||||
public TouchCharInput(@NonNull Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@ -89,20 +84,16 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText
|
||||
|
||||
/**
|
||||
* Toggle on and off the soft keyboard, depending of the state
|
||||
*
|
||||
* @return if the keyboard is set to be shown.
|
||||
*/
|
||||
public boolean switchKeyboardState(){
|
||||
public void switchKeyboardState(){
|
||||
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(INPUT_METHOD_SERVICE);
|
||||
// Allow, regardless of whether or not a hardware keyboard is declared
|
||||
if(hasFocus()){
|
||||
clear();
|
||||
disable();
|
||||
return false;
|
||||
}else{
|
||||
enable();
|
||||
imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,8 +107,8 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText
|
||||
mIsDoingInternalChanges = true;
|
||||
//Braille space, doesn't trigger keyboard auto-complete
|
||||
//replacing directly the text without though setText avoids notifying changes
|
||||
setText(" ");
|
||||
setSelection(getText().length());
|
||||
setText(TEXT_FILLER);
|
||||
setSelection(TEXT_FILLER.length());
|
||||
mIsDoingInternalChanges = false;
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,6 @@ package net.kdt.pojavlaunch.extra;
|
||||
public class ExtraConstants {
|
||||
/* ExtraCore constant: a HashMap for converting values such as latest-snapshot or latest-release to actual game version names */
|
||||
public static final String RELEASE_TABLE = "release_table";
|
||||
/* ExtraCore constant: an ArrayList of Strings, where each String is a Minecraft version name */
|
||||
public static final String VERSION_LIST = "lac_version_list";
|
||||
/* ExtraCore constant: Serpent's back button tracking thing */
|
||||
public static final String BACK_PREFERENCE = "back_preference";
|
||||
/* ExtraCore constant: The OPENGL version that should be exposed */
|
||||
|
@ -12,12 +12,13 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
*
|
||||
* This class uses a singleton pattern to simplify access to it
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public final class ExtraCore {
|
||||
// No unwanted instantiation
|
||||
private ExtraCore(){}
|
||||
|
||||
// Singleton instance
|
||||
private static ExtraCore sExtraCoreSingleton = null;
|
||||
private static volatile ExtraCore sExtraCoreSingleton = null;
|
||||
|
||||
// Store the key-value pair
|
||||
private final Map<String, Object> mValueMap = new ConcurrentHashMap<>();
|
||||
|
@ -1,7 +1,6 @@
|
||||
package net.kdt.pojavlaunch.extra;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Listener class for the ExtraCore
|
||||
@ -15,6 +14,7 @@ public interface ExtraListener<T> {
|
||||
* @param value The new value as a string
|
||||
* @return Whether you consume the Listener (stop listening)
|
||||
*/
|
||||
@SuppressWarnings("SameReturnValue")
|
||||
boolean onValueSet(String key, @NonNull T value);
|
||||
|
||||
}
|
@ -2,7 +2,6 @@ package net.kdt.pojavlaunch.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -20,7 +19,6 @@ public class LocalLoginFragment extends Fragment {
|
||||
public static final String TAG = "LOCAL_LOGIN_FRAGMENT";
|
||||
|
||||
private EditText mUsernameEditText;
|
||||
private Button mLoginButton;
|
||||
|
||||
public LocalLoginFragment(){
|
||||
super(R.layout.fragment_local_login);
|
||||
@ -29,8 +27,7 @@ public class LocalLoginFragment extends Fragment {
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
mUsernameEditText = view.findViewById(R.id.login_edit_email);
|
||||
mLoginButton = view.findViewById(R.id.login_button);
|
||||
mLoginButton.setOnClickListener(v -> {
|
||||
view.findViewById(R.id.login_button).setOnClickListener(v -> {
|
||||
if(!checkEditText()) return;
|
||||
|
||||
ExtraCore.setValue(ExtraConstants.MOJANG_LOGIN_TODO, new String[]{
|
||||
|
@ -21,8 +21,6 @@ import net.kdt.pojavlaunch.extra.ExtraConstants;
|
||||
import net.kdt.pojavlaunch.extra.ExtraCore;
|
||||
import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class MainMenuFragment extends Fragment {
|
||||
public static final String TAG = "MainMenuFragment";
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.kdt.pojavlaunch.fragments;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
@ -27,7 +28,12 @@ public class MicrosoftLoginFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
mWebview = (WebView) inflater.inflate(R.layout.fragment_microsoft_login, container, false);
|
||||
CookieManager.getInstance().removeAllCookie(); // The non deprecated method is not async
|
||||
CookieManager.getInstance().removeAllCookies(this::onCookiesRemoved);
|
||||
return mWebview;
|
||||
}
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled") // required for Microsoft log-in
|
||||
public void onCookiesRemoved(Boolean b) {
|
||||
WebSettings settings = mWebview.getSettings();
|
||||
|
||||
settings.setJavaScriptEnabled(true);
|
||||
@ -42,8 +48,6 @@ public class MicrosoftLoginFragment extends Fragment {
|
||||
"&response_type=code" +
|
||||
"&scope=service%3A%3Auser.auth.xboxlive.com%3A%3AMBI_SSL" +
|
||||
"&redirect_url=https%3A%2F%2Flogin.live.com%2Foauth20_desktop.srf");
|
||||
|
||||
return mWebview;
|
||||
}
|
||||
|
||||
/* Expose webview actions to others */
|
||||
|
@ -142,12 +142,11 @@ public class ProfileEditorFragment extends Fragment {
|
||||
|
||||
|
||||
|
||||
loadValues(LauncherPreferences.DEFAULT_PREF.getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE, ""));
|
||||
loadValues(LauncherPreferences.DEFAULT_PREF.getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE, ""), view.getContext());
|
||||
}
|
||||
|
||||
|
||||
private void loadValues(@NonNull String profile){
|
||||
Context context = getContext();
|
||||
private void loadValues(@NonNull String profile, @NonNull Context context){
|
||||
if(mTempProfile == null){
|
||||
mTempProfile = getProfile(profile);
|
||||
}
|
||||
@ -237,10 +236,4 @@ public class ProfileEditorFragment extends Fragment {
|
||||
LauncherProfiles.update();
|
||||
ExtraCore.setValue(ExtraConstants.REFRESH_VERSION_SPINNER, mProfileKey);
|
||||
}
|
||||
|
||||
/** Called on the UI thread, the profile is already saved in the files */
|
||||
public interface ProfileEditorDone {
|
||||
void onProfileSaved(MinecraftProfile profile);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import android.app.AlertDialog;
|
||||
import android.content.Intent;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
@ -34,7 +33,7 @@ public class MultiRTConfigDialog {
|
||||
public void prepare(Activity activity) {
|
||||
mDialogView = new RecyclerView(activity);
|
||||
mDialogView.setLayoutManager(new LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false));
|
||||
mDialogView.setAdapter(new RTRecyclerViewAdapter(this));
|
||||
mDialogView.setAdapter(new RTRecyclerViewAdapter());
|
||||
|
||||
mDialog = new AlertDialog.Builder(activity)
|
||||
.setTitle(R.string.multirt_config_title)
|
||||
|
@ -1,10 +1,8 @@
|
||||
package net.kdt.pojavlaunch.multirt;
|
||||
|
||||
import static net.kdt.pojavlaunch.Tools.NATIVE_LIB_DIR;
|
||||
import static net.kdt.pojavlaunch.Tools.getMinecraftClientArgs;
|
||||
import static org.apache.commons.io.FileUtils.listFiles;
|
||||
|
||||
import android.content.Context;
|
||||
import android.system.Os;
|
||||
import android.util.Log;
|
||||
|
||||
@ -20,7 +18,6 @@ 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;
|
||||
@ -41,13 +38,16 @@ public class MultiRTUtils {
|
||||
private static String sSelectedRuntimeName;
|
||||
|
||||
public static List<Runtime> getRuntimes() {
|
||||
if(!RUNTIME_FOLDER.exists()) RUNTIME_FOLDER.mkdirs();
|
||||
if(!RUNTIME_FOLDER.exists() && !RUNTIME_FOLDER.mkdirs()) {
|
||||
throw new RuntimeException("Failed to create runtime directory");
|
||||
}
|
||||
|
||||
ArrayList<Runtime> runtimes = new ArrayList<>();
|
||||
System.out.println("Fetch runtime list");
|
||||
for(File f : RUNTIME_FOLDER.listFiles()) {
|
||||
File[] files = RUNTIME_FOLDER.listFiles();
|
||||
if(files != null) for(File f : files) {
|
||||
runtimes.add(read(f.getName()));
|
||||
}
|
||||
else throw new RuntimeException("The runtime directory does not exist");
|
||||
|
||||
return runtimes;
|
||||
}
|
||||
@ -80,8 +80,6 @@ public class MultiRTUtils {
|
||||
public static void installRuntimeNamed(String nativeLibDir, InputStream runtimeInputStream, String name) throws IOException {
|
||||
File dest = new File(RUNTIME_FOLDER,"/"+name);
|
||||
if(dest.exists()) FileUtils.deleteDirectory(dest);
|
||||
dest.mkdirs();
|
||||
|
||||
uncompressTarXZ(runtimeInputStream,dest);
|
||||
runtimeInputStream.close();
|
||||
unpack200(nativeLibDir,RUNTIME_FOLDER + "/" + name);
|
||||
@ -98,17 +96,16 @@ public class MultiRTUtils {
|
||||
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);
|
||||
if(!ftIn.renameTo(ftOut)) throw new IOException("Failed to rename freetype");
|
||||
}
|
||||
|
||||
// Refresh libraries
|
||||
copyDummyNativeLib("libawt_xawt.so", dest, libFolder);
|
||||
}
|
||||
|
||||
public static Runtime installRuntimeNamedBinpack(InputStream universalFileInputStream, InputStream platformBinsInputStream, String name, String binpackVersion) throws IOException {
|
||||
public static void installRuntimeNamedBinpack(InputStream universalFileInputStream, InputStream platformBinsInputStream, String name, String binpackVersion) throws IOException {
|
||||
File dest = new File(RUNTIME_FOLDER,"/"+name);
|
||||
if(dest.exists()) FileUtils.deleteDirectory(dest);
|
||||
dest.mkdirs();
|
||||
installRuntimeNamedNoRemove(universalFileInputStream,dest);
|
||||
installRuntimeNamedNoRemove(platformBinsInputStream,dest);
|
||||
|
||||
@ -121,8 +118,7 @@ public class MultiRTUtils {
|
||||
|
||||
ProgressLayout.clearProgress(ProgressLayout.UNPACK_RUNTIME);
|
||||
|
||||
sCache.remove(name); // Force reread
|
||||
return read(name);
|
||||
forceReread(name);
|
||||
}
|
||||
|
||||
|
||||
@ -148,7 +144,7 @@ public class MultiRTUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void setRuntimeNamed(String name) throws IOException {
|
||||
public static void setRuntimeNamed(String name) {
|
||||
File dest = new File(RUNTIME_FOLDER,"/"+name);
|
||||
if((!dest.exists()) || MultiRTUtils.forceReread(name).versionString == null) throw new RuntimeException("Selected runtime is broken!");
|
||||
Tools.DIR_HOME_JRE = dest.getAbsolutePath();
|
||||
@ -185,11 +181,7 @@ public class MultiRTUtils {
|
||||
} else {
|
||||
javaVersionInt = Integer.parseInt(javaVersionSplit[0]);
|
||||
}
|
||||
Runtime runtime = new Runtime(name);
|
||||
runtime.arch = osArch;
|
||||
runtime.javaVersion = javaVersionInt;
|
||||
runtime.versionString = javaVersion;
|
||||
returnRuntime = runtime;
|
||||
returnRuntime = new Runtime(name, javaVersion, osArch, javaVersionInt);
|
||||
}else{
|
||||
returnRuntime = new Runtime(name);
|
||||
}
|
||||
@ -223,9 +215,9 @@ public class MultiRTUtils {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private static void copyDummyNativeLib(String name, File dest, String libFolder) throws IOException {
|
||||
File fileLib = new File(dest, "/"+libFolder + "/" + name);
|
||||
fileLib.delete();
|
||||
FileInputStream is = new FileInputStream(new File(NATIVE_LIB_DIR, name));
|
||||
FileOutputStream os = new FileOutputStream(fileLib);
|
||||
IOUtils.copy(is, os);
|
||||
@ -239,7 +231,8 @@ public class MultiRTUtils {
|
||||
}
|
||||
|
||||
private static void uncompressTarXZ(final InputStream tarFileInputStream, final File dest) throws IOException {
|
||||
dest.mkdirs();
|
||||
if(dest.isFile()) throw new IOException("Attempting to unpack into a file");
|
||||
if(!dest.exists() && !dest.mkdirs()) throw new IOException("Failed to create destination directory");
|
||||
|
||||
byte[] buffer = new byte[8192];
|
||||
TarArchiveInputStream tarIn = new TarArchiveInputStream(
|
||||
@ -254,8 +247,10 @@ public class MultiRTUtils {
|
||||
ProgressLayout.setProgress(ProgressLayout.UNPACK_RUNTIME, 100, R.string.global_unpacking, tarEntryName);
|
||||
|
||||
File destPath = new File(dest, tarEntry.getName());
|
||||
File destParent = destPath.getParentFile();
|
||||
if (tarEntry.isSymbolicLink()) {
|
||||
destPath.getParentFile().mkdirs();
|
||||
if(destParent != null && !destParent.exists() && !destParent.mkdirs())
|
||||
throw new IOException("Failed to create parent directory for symlink");
|
||||
try {
|
||||
// android.system.Os
|
||||
// Libcore one support all Android versions
|
||||
@ -265,11 +260,11 @@ public class MultiRTUtils {
|
||||
}
|
||||
|
||||
} else if (tarEntry.isDirectory()) {
|
||||
destPath.mkdirs();
|
||||
destPath.setExecutable(true);
|
||||
if(!destPath.exists() && !destPath.mkdirs())
|
||||
throw new IOException("Failed to create directory");
|
||||
} else if (!destPath.exists() || destPath.length() != tarEntry.getSize()) {
|
||||
destPath.getParentFile().mkdirs();
|
||||
destPath.createNewFile();
|
||||
if(destParent != null && !destParent.exists() && !destParent.mkdirs())
|
||||
throw new IOException("Failed to create parent directory for file");
|
||||
|
||||
FileOutputStream os = new FileOutputStream(destPath);
|
||||
IOUtils.copyLarge(tarIn, os, buffer);
|
||||
|
@ -26,11 +26,6 @@ import java.util.List;
|
||||
|
||||
public class RTRecyclerViewAdapter extends RecyclerView.Adapter<RTRecyclerViewAdapter.RTViewHolder> {
|
||||
|
||||
MultiRTConfigDialog mConfigDialog;
|
||||
public RTRecyclerViewAdapter(MultiRTConfigDialog dialog) {
|
||||
this.mConfigDialog = dialog;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RTViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
@ -81,6 +76,7 @@ public class RTRecyclerViewAdapter extends RecyclerView.Adapter<RTRecyclerViewAd
|
||||
itemView.findViewById(R.id.multirt_view_removebtn).setOnClickListener(this);
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged") // same as all the other ones
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if(view.getId() == R.id.multirt_view_removebtn) {
|
||||
|
@ -17,11 +17,10 @@ import java.util.List;
|
||||
|
||||
public class RTSpinnerAdapter implements SpinnerAdapter {
|
||||
final Context mContext;
|
||||
List<Runtime> mRuntimes;
|
||||
final List<Runtime> mRuntimes;
|
||||
public RTSpinnerAdapter(@NonNull Context context, List<Runtime> runtimes) {
|
||||
mRuntimes = runtimes;
|
||||
Runtime runtime = new Runtime("<Default>");
|
||||
runtime.versionString = "";
|
||||
Runtime runtime = new Runtime("<Default>", "", null, 0);
|
||||
mRuntimes.add(runtime);
|
||||
mContext = context;
|
||||
}
|
||||
|
@ -3,14 +3,24 @@ package net.kdt.pojavlaunch.multirt;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Runtime {
|
||||
public final String name;
|
||||
public final String versionString;
|
||||
public final String arch;
|
||||
public final int javaVersion;
|
||||
public Runtime(String name) {
|
||||
this.name = name;
|
||||
this.versionString = null;
|
||||
this.arch = null;
|
||||
this.javaVersion = 0;
|
||||
}
|
||||
Runtime(String name, String versionString, String arch, int javaVersion) {
|
||||
this.name = name;
|
||||
this.versionString = versionString;
|
||||
this.arch = arch;
|
||||
this.javaVersion = javaVersion;
|
||||
}
|
||||
|
||||
public String name;
|
||||
public String versionString;
|
||||
public String arch;
|
||||
public int javaVersion;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
@ -33,7 +33,7 @@ public class LauncherPreferences {
|
||||
public static String PREF_DEFAULTCTRL_PATH = Tools.CTRLDEF_FILE;
|
||||
public static String PREF_CUSTOM_JAVA_ARGS;
|
||||
public static boolean PREF_FORCE_ENGLISH = false;
|
||||
public static String PREF_VERSION_REPOS = "https://piston-meta.mojang.com/mc/game/version_manifest_v2.json";
|
||||
public static final String PREF_VERSION_REPOS = "https://piston-meta.mojang.com/mc/game/version_manifest_v2.json";
|
||||
public static boolean PREF_CHECK_LIBRARY_SHA = true;
|
||||
public static boolean PREF_DISABLE_GESTURES = false;
|
||||
public static boolean PREF_DISABLE_SWAP_HAND = false;
|
||||
|
@ -1,24 +1,18 @@
|
||||
package net.kdt.pojavlaunch.prefs.screens;
|
||||
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.os.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.preference.*;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||
|
||||
import android.content.*;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import static net.kdt.pojavlaunch.Architecture.is32BitsDevice;
|
||||
import static net.kdt.pojavlaunch.Tools.getTotalDeviceMemory;
|
||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_NOTCH_SIZE;
|
||||
|
||||
/**
|
||||
* Preference for the main screen, any sub-screen should inherit this class for consistent behavior,
|
||||
* overriding only onCreatePreferences
|
||||
|
@ -1,10 +1,7 @@
|
||||
package net.kdt.pojavlaunch.prefs.screens;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
|
||||
public class LauncherPreferenceMiscellaneousFragment extends LauncherPreferenceFragment {
|
||||
|
@ -6,7 +6,6 @@ import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.preference.SwitchPreferenceCompat;
|
||||
|
||||
|
@ -4,7 +4,6 @@ import static net.kdt.pojavlaunch.profiles.ProfileAdapter.CREATE_PROFILE_MAGIC;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@ -12,7 +11,6 @@ import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
|
||||
@ -28,11 +26,7 @@ public class ProfileIconCache {
|
||||
public static void initDefault(Context context) {
|
||||
if(sDefaultIcon != null) return;
|
||||
sDefaultIcon = ResourcesCompat.getDrawable(context.getResources(), R.mipmap.ic_launcher_foreground, null);
|
||||
sDefaultIcon.setBounds(0, 0, 10, 10);
|
||||
}
|
||||
|
||||
public static void clearIconCache() {
|
||||
sIconCache.clear();
|
||||
if(sDefaultIcon != null) sDefaultIcon.setBounds(0, 0, 10, 10);
|
||||
}
|
||||
|
||||
public static Drawable getCachedIcon(String key) {
|
||||
|
@ -6,7 +6,6 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseExpandableListAdapter;
|
||||
import android.widget.ExpandableListAdapter;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.kdt.pojavlaunch.JMinecraftVersionList;
|
||||
@ -23,17 +22,16 @@ public class VersionListAdapter extends BaseExpandableListAdapter implements Exp
|
||||
private final LayoutInflater mLayoutInflater;
|
||||
|
||||
private final String[] mGroups;
|
||||
private final List<JMinecraftVersionList.Version> mReleaseList, mSnapshotList, mBetaList, mAlphaList;
|
||||
private final String[] mInstalledVersions;
|
||||
private final List<JMinecraftVersionList.Version>[] mData;
|
||||
private final List<?>[] mData;
|
||||
|
||||
public VersionListAdapter(JMinecraftVersionList.Version[] versionList, Context ctx){
|
||||
mLayoutInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
mReleaseList = new FilteredSubList<>(versionList, item -> item.type.equals("release"));
|
||||
mSnapshotList = new FilteredSubList<>(versionList, item -> item.type.equals("snapshot"));
|
||||
mBetaList = new FilteredSubList<>(versionList, item -> item.type.equals("old_beta"));
|
||||
mAlphaList = new FilteredSubList<>(versionList, item -> item.type.equals("old_alpha"));
|
||||
List<JMinecraftVersionList.Version> releaseList = new FilteredSubList<>(versionList, item -> item.type.equals("release"));
|
||||
List<JMinecraftVersionList.Version> snapshotList = new FilteredSubList<>(versionList, item -> item.type.equals("snapshot"));
|
||||
List<JMinecraftVersionList.Version> betaList = new FilteredSubList<>(versionList, item -> item.type.equals("old_beta"));
|
||||
List<JMinecraftVersionList.Version> alphaList = new FilteredSubList<>(versionList, item -> item.type.equals("old_alpha"));
|
||||
|
||||
// Query installed versions
|
||||
mInstalledVersions = new File(Tools.DIR_GAME_NEW + "/versions").list();
|
||||
@ -44,7 +42,7 @@ public class VersionListAdapter extends BaseExpandableListAdapter implements Exp
|
||||
ctx.getString(R.string.mcl_setting_veroption_oldbeta),
|
||||
ctx.getString(R.string.mcl_setting_veroption_oldalpha)
|
||||
};
|
||||
mData = new List[]{ mReleaseList, mSnapshotList, mBetaList, mAlphaList};
|
||||
mData = new List[]{ releaseList, snapshotList, betaList, alphaList};
|
||||
}else{
|
||||
mGroups = new String[]{
|
||||
ctx.getString(R.string.mcl_setting_veroption_installed),
|
||||
@ -53,7 +51,7 @@ public class VersionListAdapter extends BaseExpandableListAdapter implements Exp
|
||||
ctx.getString(R.string.mcl_setting_veroption_oldbeta),
|
||||
ctx.getString(R.string.mcl_setting_veroption_oldalpha)
|
||||
};
|
||||
mData = new List[]{Arrays.asList(mInstalledVersions), mReleaseList, mSnapshotList, mBetaList, mAlphaList};
|
||||
mData = new List[]{Arrays.asList(mInstalledVersions), releaseList, snapshotList, betaList, alphaList};
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +75,7 @@ public class VersionListAdapter extends BaseExpandableListAdapter implements Exp
|
||||
if(isInstalledVersionSelected(groupPosition)){
|
||||
return mInstalledVersions[childPosition];
|
||||
}
|
||||
return mData[groupPosition].get(childPosition).id;
|
||||
return ((JMinecraftVersionList.Version)mData[groupPosition].get(childPosition)).id;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -109,14 +107,7 @@ public class VersionListAdapter extends BaseExpandableListAdapter implements Exp
|
||||
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
|
||||
if(convertView == null)
|
||||
convertView = mLayoutInflater.inflate(android.R.layout.simple_expandable_list_item_1, parent, false);
|
||||
if(isInstalledVersionSelected(groupPosition)){
|
||||
// Installed version is a String inside
|
||||
((TextView) convertView).setText(mInstalledVersions[childPosition]);
|
||||
}else{
|
||||
((TextView) convertView).setText(mData[groupPosition].get(childPosition).id);
|
||||
}
|
||||
|
||||
|
||||
((TextView) convertView).setText(getChild(groupPosition, childPosition));
|
||||
return convertView;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package net.kdt.pojavlaunch.services;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import net.kdt.pojavlaunch.progresskeeper.TaskCountListener;
|
||||
|
||||
|
@ -27,9 +27,8 @@ public class AsyncAssetManager {
|
||||
/**
|
||||
* Attempt to install the java 8 runtime, if necessary
|
||||
* @param am App context
|
||||
* @param otherRuntimesAvailable Whether other runtimes have been detected
|
||||
*/
|
||||
public static void unpackRuntime(AssetManager am, boolean otherRuntimesAvailable) {
|
||||
public static void unpackRuntime(AssetManager am) {
|
||||
/* Check if JRE is included */
|
||||
String rt_version = null;
|
||||
String current_rt_version = MultiRTUtils.__internal__readBinpackVersion("Internal");
|
||||
|
@ -218,7 +218,7 @@ public class AsyncMinecraftDownloader {
|
||||
(int) Math.max((float)curr/max*100,0), R.string.mcl_launch_downloading_progress, destination.getName(), curr/BYTE_TO_MB, max/BYTE_TO_MB));
|
||||
}
|
||||
|
||||
public void downloadAssets(final JAssets assets, String assetsVersion, final File outputDir) throws IOException {
|
||||
public void downloadAssets(final JAssets assets, String assetsVersion, final File outputDir) {
|
||||
LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
|
||||
final ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 500, TimeUnit.MILLISECONDS, workQueue);
|
||||
|
||||
|
@ -50,6 +50,7 @@ public class AsyncVersionList {
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private JMinecraftVersionList downloadVersionList(String mirror){
|
||||
JMinecraftVersionList list = null;
|
||||
try{
|
||||
|
@ -8,6 +8,7 @@ import java.nio.charset.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
import org.apache.commons.io.*;
|
||||
|
||||
@SuppressWarnings("IOStreamConstructor")
|
||||
public class DownloadUtils {
|
||||
public static final String USER_AGENT = Tools.APP_NAME;
|
||||
|
||||
|
@ -264,16 +264,8 @@ public class JREUtils {
|
||||
// return ldLibraryPath;
|
||||
}
|
||||
|
||||
public static int launchJavaVM(final Activity activity, String gameDirectory, final List<String> JVMArgs, final String userArgsString) throws Throwable {
|
||||
public static int launchJavaVM(final Activity activity, File gameDirectory, final List<String> JVMArgs, final String userArgsString) throws Throwable {
|
||||
JREUtils.relocateLibPath();
|
||||
// For debugging only!
|
||||
/*
|
||||
StringBuilder sbJavaArgs = new StringBuilder();
|
||||
for (String s : javaArgList) {
|
||||
sbJavaArgs.append(s + " ");
|
||||
}
|
||||
ctx.appendlnToLog("Executing JVM: \"" + sbJavaArgs.toString() + "\"");
|
||||
*/
|
||||
|
||||
setJavaEnvironment(activity);
|
||||
|
||||
@ -299,7 +291,7 @@ public class JREUtils {
|
||||
|
||||
initJavaRuntime();
|
||||
setupExitTrap(activity.getApplication());
|
||||
chdir(gameDirectory == null ? Tools.DIR_GAME_NEW : gameDirectory);
|
||||
chdir(gameDirectory == null ? Tools.DIR_GAME_NEW : gameDirectory.getAbsolutePath());
|
||||
userArgs.add(0,"java"); //argv[0] is the program name according to C standard.
|
||||
|
||||
final int exitCode = VMLauncher.launchJVM(userArgs.toArray(new String[0]));
|
||||
@ -376,45 +368,6 @@ public class JREUtils {
|
||||
return userArguments;
|
||||
}
|
||||
|
||||
/*
|
||||
* more better arguments parser that allows escapes and doesnt change up args
|
||||
* @param _args all args as a string
|
||||
* @return a list of split args
|
||||
*/
|
||||
/*public static ArrayList<String> parseJavaArguments(String _args) {
|
||||
char bracketOpen = '\0';
|
||||
char[] str = _args.toCharArray();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
ArrayList<String> ret = new ArrayList<String>();
|
||||
for(int i = 0; i < str.length; i++) {
|
||||
if(str[i] == '\\') {
|
||||
sb.append(str[i+1]);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if(str[i] == ' ' && bracketOpen == '\0') {
|
||||
if(sb.length() > 0) {
|
||||
ret.add(sb.toString());
|
||||
sb = new StringBuilder();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(str[i] == '"' || str[i] == '\'') {
|
||||
if(bracketOpen == str[i]) {
|
||||
bracketOpen = '\0';
|
||||
continue;
|
||||
}else if(bracketOpen == '\0') {
|
||||
bracketOpen = str[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
sb.append(str[i]);
|
||||
}
|
||||
ret.add(sb.toString());
|
||||
return ret;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Parse and separate java arguments in a user friendly fashion
|
||||
* It supports multi line and absence of spaces between arguments
|
||||
@ -508,16 +461,16 @@ public class JREUtils {
|
||||
* @param argStart The argument to purge from the list.
|
||||
*/
|
||||
private static void purgeArg(List<String> argList, String argStart) {
|
||||
for(int i = 0; i < argList.size(); i++) {
|
||||
final String arg = argList.get(i);
|
||||
if(arg.startsWith(argStart)) {
|
||||
argList.remove(i);
|
||||
}
|
||||
Iterator<String> args = argList.iterator();
|
||||
while(args.hasNext()) {
|
||||
String arg = args.next();
|
||||
if(arg.startsWith(argStart)) args.remove();
|
||||
}
|
||||
}
|
||||
private static final int EGL_OPENGL_ES_BIT = 0x0001;
|
||||
private static final int EGL_OPENGL_ES2_BIT = 0x0004;
|
||||
private static final int EGL_OPENGL_ES3_BIT_KHR = 0x0040;
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private static boolean hasExtension(String extensions, String name) {
|
||||
int start = extensions.indexOf(name);
|
||||
while (start >= 0) {
|
||||
|
@ -12,7 +12,7 @@ public class DependentLibrary {
|
||||
|
||||
@Keep
|
||||
public static class LibraryDownloads {
|
||||
public MinecraftLibraryArtifact artifact;
|
||||
public final MinecraftLibraryArtifact artifact;
|
||||
public LibraryDownloads(MinecraftLibraryArtifact artifact) {
|
||||
this.artifact = artifact;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import androidx.annotation.Keep;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
@SuppressWarnings("IOStreamConstructor")
|
||||
@Keep
|
||||
public class MinecraftAccount {
|
||||
public String accessToken = "0"; // access token
|
||||
|
@ -1,51 +0,0 @@
|
||||
package net.kdt.pojavlaunch.value;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftLauncherProfiles;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
@Keep
|
||||
public class PerVersionConfig {
|
||||
static File pvcFile;
|
||||
public static HashMap<String,VersionConfig> configMap;
|
||||
public static void update() throws IOException {
|
||||
if(configMap == null) {
|
||||
pvcFile = new File(Tools.DIR_GAME_HOME,"per-version-config.json");
|
||||
if(pvcFile.exists()) {
|
||||
try {
|
||||
configMap = Tools.GLOBAL_GSON.fromJson(Tools.read(pvcFile.getAbsolutePath()), new TypeToken<HashMap<String, VersionConfig>>() {
|
||||
}.getType());
|
||||
}catch(JsonSyntaxException ex) {
|
||||
ex.printStackTrace();
|
||||
configMap = new HashMap<>();
|
||||
}
|
||||
}else{
|
||||
configMap = new HashMap<>();
|
||||
}
|
||||
}else{
|
||||
Tools.write(pvcFile.getAbsolutePath(),Tools.GLOBAL_GSON.toJson(configMap));
|
||||
}
|
||||
}
|
||||
public static boolean erase() {
|
||||
return new File(Tools.DIR_GAME_HOME,"per-version-config.json").delete();
|
||||
}
|
||||
public static boolean exists() {
|
||||
return new File(Tools.DIR_GAME_HOME,"per-version-config.json").exists();
|
||||
}
|
||||
|
||||
@Keep
|
||||
public static class VersionConfig {
|
||||
public String jvmArgs;
|
||||
public String gamePath;
|
||||
public String selectedRuntime;
|
||||
public String renderer;
|
||||
}
|
||||
}
|
@ -1,16 +1,17 @@
|
||||
package net.kdt.pojavlaunch.value.launcherprofiles;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.gson.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
import java.io.*;
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public class LauncherProfiles {
|
||||
public static MinecraftLauncherProfiles mainProfileJson;
|
||||
public static File launcherProfilesFile = new File(Tools.DIR_GAME_NEW + "/launcher_profiles.json");
|
||||
public static final File launcherProfilesFile = new File(Tools.DIR_GAME_NEW, "launcher_profiles.json");
|
||||
public static MinecraftLauncherProfiles update() {
|
||||
try {
|
||||
if (mainProfileJson == null) {
|
||||
@ -47,7 +48,7 @@ public class LauncherProfiles {
|
||||
// Detect denormalized keys
|
||||
for(String profileKey : launcherProfiles.profiles.keySet()){
|
||||
try{
|
||||
UUID.fromString(profileKey);
|
||||
if(!UUID.fromString(profileKey).toString().equals(profileKey)) keys.add(profileKey);
|
||||
}catch (IllegalArgumentException exception){
|
||||
keys.add(profileKey);
|
||||
Log.w(LauncherProfiles.class.toString(), "Illegal profile uuid: " + profileKey);
|
||||
@ -68,14 +69,4 @@ public class LauncherProfiles {
|
||||
|
||||
return hasNormalized;
|
||||
}
|
||||
/*
|
||||
public static String insert;
|
||||
|
||||
private static void insertMissing() {
|
||||
if (mainProfileJson.authenticationDatabase == null) {
|
||||
MinecraftAuthenticationDatabase mad = new MinecraftAuthenticationDatabase();
|
||||
mainProfileJson.authenticationDatabase = mad;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user