Cleanup, part 2

This commit is contained in:
artdeell 2023-04-30 21:30:11 +03:00
parent 57b37dfc8c
commit 8e669caa2e
63 changed files with 423 additions and 707 deletions

View File

@ -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;

View File

@ -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();
}
/**

View File

@ -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");
}
/**

View File

@ -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);
}

View File

@ -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()) {

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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());
}
}

View File

@ -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";
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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){

View File

@ -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)

View File

@ -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));

View File

@ -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++; }

View File

@ -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){

View File

@ -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

View File

@ -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()){

View File

@ -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){

View File

@ -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);

View File

@ -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;

View File

@ -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[]{};

View File

@ -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;
}

View File

@ -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;

View File

@ -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")

View File

@ -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()){

View File

@ -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")

View File

@ -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();
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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 */

View File

@ -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<>();

View File

@ -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);
}

View File

@ -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[]{

View File

@ -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";

View File

@ -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 */

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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);

View File

@ -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) {

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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 {

View File

@ -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;

View File

@ -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) {

View File

@ -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;
}

View File

@ -1,7 +1,6 @@
package net.kdt.pojavlaunch.services;
import android.content.Context;
import android.util.Log;
import net.kdt.pojavlaunch.progresskeeper.TaskCountListener;

View File

@ -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");

View File

@ -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);

View File

@ -50,6 +50,7 @@ public class AsyncVersionList {
}
@SuppressWarnings("SameParameterValue")
private JMinecraftVersionList downloadVersionList(String mirror){
JMinecraftVersionList list = null;
try{

View File

@ -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;

View File

@ -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) {

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}
}
*/
}