diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..6b21200f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Natives/external/DBNumberedSlider"] + path = Natives/external/DBNumberedSlider + url = https://github.com/immago/DBNumberedSlider diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/InstallerTask.java.todo b/JavaApp/src/main/java/net/kdt/pojavlaunch/InstallerTask.java.todo deleted file mode 100644 index 5e6b84f2..00000000 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/InstallerTask.java.todo +++ /dev/null @@ -1,52 +0,0 @@ -package net.kdt.pojavlaunch; -import android.os.*; - -public class InstallerTask extends AsyncTask -{ - @Override - protected String doInBackground(String[] p1) - { - try - { - downloadLibraries(p1[0]); - dexMinecraftLibs(); - downloadMinecraft(p1[0]); - dexMinecraftClient(p1[0]); - downloadAssets(p1[0]); - } - catch (Exception e) - { - return e.getMessage(); - } - return null; - } - @Override - protected void onPostExecute(String result) - { - super.onPostExecute(result); - - if(result == null){ - //No errors - } - } - private void downloadLibraries(String versionName) throws Exception - { - - } - private void dexMinecraftLibs() throws Exception - { - - } - private void downloadMinecraft(String versionName) throws Exception - { - - } - private void dexMinecraftClient(String version) throws Exception - { - - } - private void downloadAssets(String versionName) throws Exception - { - - } -} diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/PLaunchApp.java b/JavaApp/src/main/java/net/kdt/pojavlaunch/PLaunchApp.java index 6fb058fa..e3e26b30 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/PLaunchApp.java +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/PLaunchApp.java @@ -6,7 +6,6 @@ import java.util.concurrent.*; import org.lwjgl.glfw.CallbackBridge; -import net.kdt.pojavlaunch.prefs.*; import net.kdt.pojavlaunch.uikit.*; import net.kdt.pojavlaunch.utils.*; import net.kdt.pojavlaunch.value.*; @@ -23,14 +22,10 @@ public class PLaunchApp { File mcDir = new File(Tools.DIR_GAME_NEW); mcDir.mkdirs(); new File(Tools.DIR_ACCOUNT_NEW).mkdirs(); - if (!new File(Tools.DIR_APP_DATA, "config_ver.txt").exists()) { - Tools.write(Tools.DIR_APP_DATA + "/config_ver.txt", "1.16.5"); - + if (!new File(mcDir.getAbsolutePath() + "/launcher_profiles.json").exists()) { Tools.write(mcDir.getAbsolutePath() + "/launcher_profiles.json", Tools.read(Tools.DIR_DATA + "/launcher_profiles.json")); } - - LauncherPreferences.loadPreferences(); } catch (IOException e) { e.printStackTrace(); } @@ -62,9 +57,13 @@ public class PLaunchApp { String mcver = "1.16.5"; try { - mcver = Tools.read(Tools.DIR_APP_DATA + "/config_ver.txt"); + String plistContent = Tools.read(Tools.DIR_APP_DATA + "/launcher_preferences.plist"); + plistContent = plistContent.substring(plistContent.indexOf("selected_version") + 26); + plistContent = plistContent.replace("", "") + .substring(0, plistContent.indexOf("")).trim(); } catch (IOException e) { - UIKit.updateProgressSafe(0, "config_ver.txt not found, defaulting to Minecraft 1.16.5"); + e.printStackTrace(); + UIKit.updateProgressSafe(0, "Could not parse plist, defaulting to Minecraft 1.16.5"); } AccountJNI.CURRENT_ACCOUNT.selectedVersion = mcver; diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java b/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java index 4ce1a644..b28e1ea3 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -31,7 +31,6 @@ import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; -import net.kdt.pojavlaunch.prefs.LauncherPreferences; import net.kdt.pojavlaunch.uikit.UIKit; import net.kdt.pojavlaunch.utils.DownloadUtils; import net.kdt.pojavlaunch.utils.JSONUtils; @@ -59,7 +58,7 @@ public final class Tools public static final String DIR_GAME_HOME = System.getenv("HOME") + "/Documents"; public static final String DIR_GAME_NEW = DIR_GAME_HOME + "/minecraft"; - public static final String DIR_APP_DATA = DIR_GAME_HOME + "/.pojavlauncher"; + public static final String DIR_APP_DATA = System.getenv("POJAV_HOME"); public static final String DIR_ACCOUNT_NEW = DIR_APP_DATA + "/accounts"; // New since 3.0.0 @@ -295,89 +294,7 @@ public final class Tools return libStr.toString(); } -/* - public static DisplayMetrics getDisplayMetrics(Activity ctx) { - DisplayMetrics displayMetrics = new DisplayMetrics(); - ctx.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); - return displayMetrics; - } - public static void setFullscreen(Activity act) { - final View decorView = act.getWindow().getDecorView(); - decorView.setOnSystemUiVisibilityChangeListener (new View.OnSystemUiVisibilityChangeListener() { - @Override - public void onSystemUiVisibilityChange(int visibility) { - if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { - decorView.setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); - } - } - }); - } - - public static DisplayMetrics currentDisplayMetrics; - public static void updateWindowSize(Activity ctx) { - currentDisplayMetrics = getDisplayMetrics(ctx); - CallbackBridge.windowWidth = currentDisplayMetrics.widthPixels; - CallbackBridge.windowHeight = currentDisplayMetrics.heightPixels; - - if (CallbackBridge.windowWidth < CallbackBridge.windowHeight) { - CallbackBridge.windowWidth = currentDisplayMetrics.heightPixels; - CallbackBridge.windowHeight = currentDisplayMetrics.widthPixels; - } - } - - public static float dpToPx(float dp) { - // 921600 = 1280 * 720, default scale - // TODO better way to scaling - float scaledDp = dp; // / DisplayMetrics.DENSITY_XHIGH * currentDisplayMetrics.densityDpi; - return (scaledDp * currentDisplayMetrics.density); - } - - public static void copyAssetFile(Context ctx, String fileName, String output, boolean overwrite) throws IOException { - copyAssetFile(ctx, fileName, output, new File(fileName).getName(), overwrite); - } - - public static void copyAssetFile(Context ctx, String fileName, String output, String outputName, boolean overwrite) throws IOException - { - File file = new File(output); - if(!file.exists()) { - file.mkdirs(); - } - File file2 = new File(output, outputName); - if(!file2.exists() || overwrite){ - write(file2.getAbsolutePath(), loadFromAssetToByte(ctx, fileName)); - } - } - - public static void extractAssetFolder(Activity ctx, String path, String output) throws Exception { - extractAssetFolder(ctx, path, output, false); - } - - public static void extractAssetFolder(Activity ctx, String path, String output, boolean overwrite) throws Exception { - AssetManager assetManager = ctx.getAssets(); - String assets[] = null; - try { - assets = assetManager.list(path); - if (assets.length == 0) { - Tools.copyAssetFile(ctx, path, output, overwrite); - } else { - File dir = new File(output, path); - if (!dir.exists()) - dir.mkdirs(); - for (String sub : assets) { - extractAssetFolder(ctx, path + "/" + sub, output, overwrite); - } - } - } catch (Exception e) { - showError(ctx, e); - } - } -*/ public static void showError(Throwable e) { showError(e, false); } diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java b/JavaApp/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java deleted file mode 100644 index e0c4de5a..00000000 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java +++ /dev/null @@ -1,85 +0,0 @@ -package net.kdt.pojavlaunch.prefs; - -import java.io.*; -import java.util.*; -import net.kdt.pojavlaunch.*; - -public class LauncherPreferences -{ - // public static SharedPreferences DEFAULT_PREF; - public static boolean PREF_VERTYPE_RELEASE = true; - public static boolean PREF_VERTYPE_SNAPSHOT = false; - public static boolean PREF_VERTYPE_OLDALPHA = false; - public static boolean PREF_VERTYPE_OLDBETA = false; - public static boolean PREF_FREEFORM = false; - public static float PREF_BUTTONSIZE = 100f; - public static float PREF_MOUSESCALE = 100f; - public static int PREF_LONGPRESS_TRIGGER = 500; - public static String PREF_DEFAULTCTRL_PATH = Tools.CTRLDEF_FILE; - public static String PREF_CUSTOM_JAVA_ARGS; - public static String PREF_CUSTOM_OPENGL_LIBNAME = "libgl4es_114.dylib"; - public static String PREF_LANGUAGE = "default"; - - public static void loadPreferences() { -/* - PREF_BUTTONSIZE = DEFAULT_PREF.getInt("buttonscale", 100); - PREF_MOUSESCALE = DEFAULT_PREF.getInt("mousescale", 100); - PREF_FREEFORM = DEFAULT_PREF.getBoolean("freeform", false); - PREF_VERTYPE_RELEASE = DEFAULT_PREF.getBoolean("vertype_release", true); - PREF_VERTYPE_SNAPSHOT = DEFAULT_PREF.getBoolean("vertype_snapshot", false); - PREF_VERTYPE_OLDALPHA = DEFAULT_PREF.getBoolean("vertype_oldalpha", false); - PREF_VERTYPE_OLDBETA = DEFAULT_PREF.getBoolean("vertype_oldbeta", false); - PREF_LONGPRESS_TRIGGER = DEFAULT_PREF.getInt("timeLongPressTrigger", 500); - PREF_DEFAULTCTRL_PATH = DEFAULT_PREF.getString("defaultCtrl", Tools.CTRLDEF_FILE); - PREF_LANGUAGE = DEFAULT_PREF.getString("language", "default"); - - // Get double of max Android heap to set default heap size - int androidHeap = (int) (Runtime.getRuntime().maxMemory() / 1024l / 512l); - int doubleAndroidHeap = androidHeap * 2; - // PREF_CUSTOM_JAVA_ARGS = DEFAULT_PREF.getString("javaArgs", ""); - if (PREF_CUSTOM_JAVA_ARGS.isEmpty()) { - String DEFAULT_JAVA_ARGS = - "-Xms" + (androidHeap > 800 ? 800 : androidHeap) + "m " + - // (32bit) More than 800mb may make JVM not allocateable and crash - "-Xmx" + (doubleAndroidHeap > 800 ? 800 : doubleAndroidHeap) + "m " + - "-XX:+UseG1GC " + - "-XX:+ParallelRefProcEnabled " + - "-XX:MaxGCPauseMillis=200 " + - "-XX:+UnlockExperimentalVMOptions " + - "-XX:+AlwaysPreTouch " + - "-XX:G1NewSizePercent=30 " + - "-XX:G1MaxNewSizePercent=40 " + - "-XX:G1HeapRegionSize=8M " + - "-XX:G1ReservePercent=20 " + - "-XX:G1HeapWastePercent=5 " + - "-XX:G1MixedGCCountTarget=4 " + - "-XX:InitiatingHeapOccupancyPercent=15 " + - "-XX:G1MixedGCLiveThresholdPercent=90 " + - "-XX:G1RSetUpdatingPauseTimePercent=5 " + - "-XX:SurvivorRatio=32 " + - "-XX:+PerfDisableSharedMem " + - "-XX:MaxTenuringThreshold=1"; - - PREF_CUSTOM_JAVA_ARGS = DEFAULT_JAVA_ARGS; - DEFAULT_PREF.edit().putString("javaArgs", DEFAULT_JAVA_ARGS).commit(); - } - - String argLwjglLibname = "-Dorg.lwjgl.opengl.libname="; - for (String arg : PREF_CUSTOM_JAVA_ARGS.split(" ")) { - if (arg.startsWith(argLwjglLibname)) { - PREF_CUSTOM_OPENGL_LIBNAME = arg.substring(argLwjglLibname.length()); - } - } -*/ - - File argsFile = new File(Tools.DIR_APP_DATA, "overrideargs.txt"); - try { - if (!argsFile.exists()) { - argsFile.createNewFile(); - } - PREF_CUSTOM_JAVA_ARGS = Tools.read(argsFile.getAbsolutePath()); - } catch (IOException e) { - e.printStackTrace(); - } - } -} diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java.todo b/JavaApp/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java.todo deleted file mode 100644 index 5960abbc..00000000 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java.todo +++ /dev/null @@ -1,337 +0,0 @@ -package net.kdt.pojavlaunch.tasks; - -import android.app.*; -import android.content.*; -import android.graphics.*; -import android.os.*; -import android.util.*; -import com.google.gson.*; -import java.io.*; -import java.util.*; -import net.kdt.pojavlaunch.*; -import net.kdt.pojavlaunch.prefs.*; -import net.kdt.pojavlaunch.utils.*; -import net.kdt.pojavlaunch.value.*; -import org.apache.commons.io.*; - -public class MinecraftDownloaderTask extends AsyncTask - { - private BaseLauncherActivity mActivity; - private boolean launchWithError = false; - MinecraftDownloaderTask thiz = this; - public MinecraftDownloaderTask(BaseLauncherActivity activity) { - mActivity = activity; - } - - @Override - protected void onPreExecute() { - mActivity.mLaunchProgress.setMax(1); - mActivity.statusIsLaunching(true); - } - - private JMinecraftVersionList.Version verInfo; - @Override - protected Throwable doInBackground(final String[] p1) { - Throwable throwable = null; - try { - final String downVName = "/" + p1[0] + "/" + p1[0]; - //Downloading libraries - String minecraftMainJar = Tools.DIR_HOME_VERSION + downVName + ".jar"; - JAssets assets = null; - try { - String verJsonDir = Tools.DIR_HOME_VERSION + downVName + ".json"; - - verInfo = findVersion(p1[0]); - - if (verInfo.url != null && !new File(verJsonDir).exists()) { - publishProgress("1", mActivity.getString(R.string.mcl_launch_downloading, p1[0] + ".json")); - - Tools.downloadFileMonitored( - verInfo.url, - verJsonDir, - new Tools.DownloaderFeedback(){ - @Override - public void updateProgress(int curr, int max) { - publishDownloadProgress(p1[0] + ".json", curr, max); - } - } - ); - } - - verInfo = Tools.getVersionInfo(p1[0]); - assets = downloadIndex(verInfo.assets, new File(Tools.ASSETS_PATH, "indexes/" + verInfo.assets + ".json")); - - File outLib; - String libPathURL; - - setMax(verInfo.libraries.length); - zeroProgress(); - for (final DependentLibrary libItem : verInfo.libraries) { - - if ( - libItem.name.startsWith("net.java.jinput") || - libItem.name.startsWith("org.lwjgl") - ) { // Black list - publishProgress("1", "Ignored " + libItem.name); - //Thread.sleep(100); - } else { - String[] libInfo = libItem.name.split(":"); - String libArtifact = Tools.artifactToPath(libInfo[0], libInfo[1], libInfo[2]); - outLib = new File(Tools.DIR_HOME_LIBRARY + "/" + libArtifact); - outLib.getParentFile().mkdirs(); - - if (!outLib.exists()) { - publishProgress("1", mActivity.getString(R.string.mcl_launch_downloading, libItem.name)); - - boolean skipIfFailed = false; - - if (libItem.downloads == null || libItem.downloads.artifact == null) { - MinecraftLibraryArtifact artifact = new MinecraftLibraryArtifact(); - artifact.url = (libItem.url == null ? "https://libraries.minecraft.net/" : libItem.url) + libArtifact; - libItem.downloads = new DependentLibrary.LibraryDownloads(artifact); - - skipIfFailed = true; - } - try { - libPathURL = libItem.downloads.artifact.url; - Tools.downloadFileMonitored( - libPathURL, - outLib.getAbsolutePath(), - new Tools.DownloaderFeedback() { - @Override - public void updateProgress(int curr, int max) { - publishDownloadProgress(libItem.name, curr, max); - } - } - ); - } catch (Throwable th) { - if (!skipIfFailed) { - throw th; - } else { - th.printStackTrace(); - publishProgress("0", th.getMessage()); - } - } - } - } - } - setMax(3); - zeroProgress(); - publishProgress("1", mActivity.getString(R.string.mcl_launch_downloading, p1[0] + ".jar")); - File minecraftMainFile = new File(minecraftMainJar); - if (!minecraftMainFile.exists() || minecraftMainFile.length() == 0l) { - try { - Tools.downloadFileMonitored( - verInfo.downloads.values().toArray(new MinecraftClientInfo[0])[0].url, - minecraftMainJar, - new Tools.DownloaderFeedback() { - @Override - public void updateProgress(int curr, int max) { - publishDownloadProgress(p1[0] + ".jar", curr, max); - } - } - ); - } catch (Throwable th) { - if (verInfo.inheritsFrom != null) { - minecraftMainFile.delete(); - FileInputStream is = new FileInputStream(new File(Tools.DIR_HOME_VERSION, verInfo.inheritsFrom + "/" + verInfo.inheritsFrom + ".jar")); - FileOutputStream os = new FileOutputStream(minecraftMainFile); - IOUtils.copy(is, os); - is.close(); - os.close(); - } else { - throw th; - } - } - } - } catch (Throwable e) { - launchWithError = true; - throw e; - } - - publishProgress("1", mActivity.getString(R.string.mcl_launch_cleancache)); - // new File(inputPath).delete(); - - for (File f : new File(Tools.DIR_HOME_VERSION).listFiles()) { - if(f.getName().endsWith(".part")) { - System.out.println("Cleaning cache: " + f); - f.delete(); - } - } - - mActivity.mIsAssetsProcessing = true; - mActivity.mPlayButton.post(new Runnable(){ - - @Override - public void run() - { - mActivity.mPlayButton.setText("Skip"); - mActivity.mPlayButton.setEnabled(true); - } - }); - publishProgress("1", mActivity.getString(R.string.mcl_launch_download_assets)); - setMax(assets.objects.size()); - zeroProgress(); - try { - downloadAssets(assets, verInfo.assets, new File(Tools.ASSETS_PATH)); - } catch (Exception e) { - e.printStackTrace(); - - // Ignore it - launchWithError = false; - } finally { - mActivity.mIsAssetsProcessing = false; - } - } catch (Throwable th){ - throwable = th; - } finally { - return throwable; - } - } - private int addProgress = 0; - - public void zeroProgress() { - addProgress = 0; - } - - public void setMax(final int value) - { - mActivity.mLaunchProgress.post(new Runnable(){ - - @Override - public void run() - { - mActivity.mLaunchProgress.setMax(value); - } - }); - } - - private void publishDownloadProgress(String target, int curr, int max) { - // array length > 2 ignores append log on dev console - publishProgress("0", mActivity.getString(R.string.mcl_launch_downloading_progress, target, - curr / 1024d / 1024d, max / 1024d / 1024d), ""); - } - - @Override - protected void onProgressUpdate(String... p1) - { - int addedProg = Integer.parseInt(p1[0]); - if (addedProg != -1) { - addProgress = addProgress + addedProg; - mActivity.mLaunchProgress.setProgress(addProgress); - - mActivity.mLaunchTextStatus.setText(p1[1]); - } - - if (p1.length < 3) { - mActivity.mConsoleView.putLog(p1[1] + "\n"); - } - } - - @Override - protected void onPostExecute(Throwable p1) - { - mActivity.mPlayButton.setText("Play"); - mActivity.mPlayButton.setEnabled(true); - mActivity.mLaunchProgress.setMax(100); - mActivity.mLaunchProgress.setProgress(0); - mActivity.statusIsLaunching(false); - if(p1 != null) { - p1.printStackTrace(); - Tools.showError(mActivity, p1); - } - if(!launchWithError) { - mActivity.mCrashView.setLastCrash(""); - - try { - /* - List jvmArgs = ManagementFactory.getRuntimeMXBean().getInputArguments(); - jvmArgs.add("-Xms128M"); - jvmArgs.add("-Xmx1G"); - */ - Intent mainIntent = new Intent(mActivity, MainActivity.class /* MainActivity.class */); - // mainIntent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT); - mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); - mainIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); - if (LauncherPreferences.PREF_FREEFORM) { - DisplayMetrics dm = new DisplayMetrics(); - mActivity.getWindowManager().getDefaultDisplay().getMetrics(dm); - - ActivityOptions options = (ActivityOptions) ActivityOptions.class.getMethod("makeBasic").invoke(null); - Rect freeformRect = new Rect(0, 0, dm.widthPixels / 2, dm.heightPixels / 2); - options.getClass().getDeclaredMethod("setLaunchBounds", Rect.class).invoke(options, freeformRect); - mActivity.startActivity(mainIntent, options.toBundle()); - } else { - mActivity.startActivity(mainIntent); - } - } - catch (Throwable e) { - Tools.showError(mActivity, e); - } - - /* - FloatingIntent maini = new FloatingIntent(PojavLauncherActivity.this, MainActivity.class); - maini.startFloatingActivity(); - */ - } - - mActivity.mTask = null; - } - - public static final String MINECRAFT_RES = "https://resources.download.minecraft.net/"; - - public JAssets downloadIndex(String versionName, File output) throws Throwable { - if (!output.exists()) { - output.getParentFile().mkdirs(); - DownloadUtils.downloadFile(verInfo.assetIndex != null ? verInfo.assetIndex.url : "http://s3.amazonaws.com/Minecraft.Download/indexes/" + versionName + ".json", output); - } - - return Tools.GLOBAL_GSON.fromJson(Tools.read(output.getAbsolutePath()), JAssets.class); - } - - public void downloadAsset(JAssetInfo asset, File objectsDir) throws IOException, Throwable { - String assetPath = asset.hash.substring(0, 2) + "/" + asset.hash; - File outFile = new File(objectsDir, assetPath); - if (!outFile.exists()) { - DownloadUtils.downloadFile(MINECRAFT_RES + assetPath, outFile); - } - } - - public void downloadAssets(JAssets assets, String assetsVersion, File outputDir) throws IOException, Throwable { - File hasDownloadedFile = new File(outputDir, "downloaded/" + assetsVersion + ".downloaded"); - if (!hasDownloadedFile.exists()) { - System.out.println("Assets begin time: " + System.currentTimeMillis()); - Map assetsObjects = assets.objects; - mActivity.mLaunchProgress.setMax(assetsObjects.size()); - zeroProgress(); - File objectsDir = new File(outputDir, "objects"); - int downloadedSs = 0; - for (JAssetInfo asset : assetsObjects.values()) { - if (!mActivity.mIsAssetsProcessing) { - return; - } - - downloadAsset(asset, objectsDir); - publishProgress("1", mActivity.getString(R.string.mcl_launch_downloading, assetsObjects.keySet().toArray(new String[0])[downloadedSs])); - downloadedSs++; - } - hasDownloadedFile.getParentFile().mkdirs(); - hasDownloadedFile.createNewFile(); - System.out.println("Assets end time: " + System.currentTimeMillis()); - } - } - - - private JMinecraftVersionList.Version findVersion(String version) { - if (mActivity.mVersionList != null) { - for (JMinecraftVersionList.Version valueVer: mActivity.mVersionList.versions) { - if (valueVer.id.equals(version)) { - return valueVer; - } - } - } - - // Custom version, inherits from base. - return Tools.getVersionInfo(version); - } -} diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/tasks/RefreshVersionListTask.java.todo b/JavaApp/src/main/java/net/kdt/pojavlaunch/tasks/RefreshVersionListTask.java.todo deleted file mode 100644 index f60507cd..00000000 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/tasks/RefreshVersionListTask.java.todo +++ /dev/null @@ -1,132 +0,0 @@ -package net.kdt.pojavlaunch.tasks; - -import android.os.*; -import androidx.appcompat.widget.*; -import android.view.*; -import android.widget.*; -import android.widget.AdapterView.*; - -import java.io.*; -import java.util.*; -import net.kdt.pojavlaunch.*; -import net.kdt.pojavlaunch.prefs.*; -import net.kdt.pojavlaunch.utils.*; - -import androidx.appcompat.widget.PopupMenu; - -public class RefreshVersionListTask extends AsyncTask> -{ - private BaseLauncherActivity mActivity; - - public RefreshVersionListTask(BaseLauncherActivity activity) { - mActivity = activity; - } - - @Override - protected ArrayList doInBackground(Void[] p1) - { - try { - mActivity.mVersionList = Tools.GLOBAL_GSON.fromJson(DownloadUtils.downloadString("https://launchermeta.mojang.com/mc/game/version_manifest.json"), JMinecraftVersionList.class); - ArrayList versionStringList = filter(mActivity.mVersionList.versions, new File(Tools.DIR_HOME_VERSION).listFiles()); - - return versionStringList; - } catch (Exception e){ - e.printStackTrace(); - } - return null; - } - - @Override - protected void onPostExecute(ArrayList result) - { - super.onPostExecute(result); - - final PopupMenu popup = new PopupMenu(mActivity, mActivity.mVersionSelector); - popup.getMenuInflater().inflate(R.menu.menu_versionopt, popup.getMenu()); - - if(result != null && result.size() > 0) { - ArrayAdapter adapter = new ArrayAdapter(mActivity, android.R.layout.simple_spinner_item, result); - adapter.setDropDownViewResource(android.R.layout.simple_list_item_single_choice); - mActivity.mVersionSelector.setAdapter(adapter); - mActivity.mVersionSelector.setSelection(selectAt(result.toArray(new String[0]), mActivity.mProfile.selectedVersion)); - } else { - mActivity.mVersionSelector.setSelection(selectAt(mActivity.mAvailableVersions, mActivity.mProfile.selectedVersion)); - } - mActivity.mVersionSelector.setOnItemSelectedListener(new OnItemSelectedListener(){ - - @Override - public void onItemSelected(AdapterView p1, View p2, int p3, long p4) - { - String version = p1.getItemAtPosition(p3).toString(); - mActivity.mProfile.selectedVersion = version; - - PojavProfile.setCurrentProfile(mActivity, mActivity.mProfile); - if (PojavProfile.isFileType(mActivity)) { - try { - PojavProfile.setCurrentProfile(mActivity, mActivity.mProfile.save()); - } catch (IOException e) { - Tools.showError(mActivity, e); - } - } - - mActivity.mTextVersion.setText(mActivity.getString(R.string.mcl_version_msg, version)); - } - - @Override - public void onNothingSelected(AdapterView p1) - { - // TODO: Implement this method - } - }); - mActivity.mVersionSelector.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){ - @Override - public boolean onItemLongClick(AdapterView p1, View p2, int p3, long p4) - { - // Implement copy, remove, reinstall,... - popup.show(); - return true; - } - }); - - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - return true; - } - }); - - mActivity.mTextVersion.setText(mActivity.getString(R.string.mcl_version_msg) + mActivity.mVersionSelector.getSelectedItem()); - } - - private ArrayList filter(JMinecraftVersionList.Version[] list1, File[] list2) { - ArrayList output = new ArrayList(); - - for (JMinecraftVersionList.Version value1: list1) { - if ((value1.type.equals("release") && LauncherPreferences.PREF_VERTYPE_RELEASE) || - (value1.type.equals("snapshot") && LauncherPreferences.PREF_VERTYPE_SNAPSHOT) || - (value1.type.equals("old_alpha") && LauncherPreferences.PREF_VERTYPE_OLDALPHA) || - (value1.type.equals("old_beta") && LauncherPreferences.PREF_VERTYPE_OLDBETA)) { - output.add(value1.id); - } - } - - for (File value2: list2) { - if (!output.contains(value2.getName())) { - output.add(value2.getName()); - } - } - - return output; - } - - private int selectAt(String[] strArr, String select) { - int count = 0; - for(String str : strArr){ - if (str.equals(select)) { - return count; - } else { - count++; - } - } - return -1; - } -} diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java b/JavaApp/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java index 50a5f3df..2ef5a7e4 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java @@ -10,130 +10,14 @@ import java.util.*; // import libcore.io.*; import net.kdt.pojavlaunch.*; -import net.kdt.pojavlaunch.prefs.*; import org.lwjgl.glfw.*; public class JREUtils { private JREUtils() {} - - public static String LD_LIBRARY_PATH; - private static String nativeLibDir; - public static String findInLdLibPath(String libName) { - for (String libPath : System.getenv("LD_LIBRARY_PATH").split(":")) { - File f = new File(libPath, libName); - if (f.exists() && f.isFile()) { - return f.getAbsolutePath(); - } - } - return libName; - } - - public static void initJavaRuntime() { -/* - dlopen(findInLdLibPath("libjli.dylib")); - dlopen(findInLdLibPath("libjvm.dylib")); - dlopen(findInLdLibPath("libverify.dylib")); - dlopen(findInLdLibPath("libjava.dylib")); - // dlopen(findInLdLibPath("libjsig.so")); - dlopen(findInLdLibPath("libnet.dylib")); - dlopen(findInLdLibPath("libnio.dylib")); - dlopen(findInLdLibPath("libawt.dylib")); - dlopen(findInLdLibPath("libawt_headless.dylib")); - dlopen(findInLdLibPath("libfreetype.dylib")); - dlopen(findInLdLibPath("libfontmanager.dylib")); -*/ - - dlopen(nativeLibDir + "/libopenal.dylib"); -/* - if (LauncherPreferences.PREF_CUSTOM_OPENGL_LIBNAME.equals("libgl04es.so")) { - LauncherPreferences.PREF_CUSTOM_OPENGL_LIBNAME = nativeLibDir + "/libgl04es.so"; - } - if (!dlopen(LauncherPreferences.PREF_CUSTOM_OPENGL_LIBNAME) && !dlopen(findInLdLibPath(LauncherPreferences.PREF_CUSTOM_OPENGL_LIBNAME))) { - System.err.println("Failed to load custom OpenGL library " + LauncherPreferences.PREF_CUSTOM_OPENGL_LIBNAME + ". Fallbacking to GL4ES."); - dlopen(nativeLibDir + "/libgl04es.so"); - } -*/ - } - - public static Map readJREReleaseProperties() throws IOException { - Map jreReleaseMap = new ArrayMap<>(); - BufferedReader jreReleaseReader = new BufferedReader(new FileReader(Tools.DIR_HOME_JRE + "/release")); - String currLine; - while ((currLine = jreReleaseReader.readLine()) != null) { - if (!currLine.isEmpty() || currLine.contains("=")) { - String[] keyValue = currLine.split("="); - jreReleaseMap.put(keyValue[0], keyValue[1].replace("\"", "")); - } - } - jreReleaseReader.close(); - return jreReleaseMap; - } - - private static boolean checkAccessTokenLeak = true; - public static void redirectAndPrintJRELog(final String accessToken) { - } - - public static void relocateLibPath() throws Exception { - StringBuilder ldLibraryPath = new StringBuilder(); - ldLibraryPath.append( - // To make libjli.so ignore re-execute - Tools.DIR_HOME_JRE + "/" + Tools.DIRNAME_HOME_JRE + "/server:" + - Tools.DIR_HOME_JRE + "/" + Tools.DIRNAME_HOME_JRE + "/jli:" + - Tools.DIR_HOME_JRE + "/" + Tools.DIRNAME_HOME_JRE + ":" + - Tools.DIR_DATA + "/Frameworks:"+ - System.getenv("DYLD_LIBRARY_PATH") - ); - - LD_LIBRARY_PATH = ldLibraryPath.toString(); - } - - public static void setJavaEnvironment() throws Throwable { - Map envMap = new ArrayMap<>(); - envMap.put("JAVA_HOME", Tools.DIR_HOME_JRE); - envMap.put("HOME", Tools.DIR_GAME_NEW); - envMap.put("TMPDIR", System.getProperty("java.io.tmpdir")); - envMap.put("LIBGL_MIPMAP", "3"); - - // Fix white color on banner and sheep, since GL4ES 1.1.5 - envMap.put("LIBGL_NORMALIZE", "1"); - - envMap.put("MESA_GLSL_CACHE_DIR", System.getProperty("java.io.tmpdir")); - envMap.put("DYLD_LIBRARY_PATH", LD_LIBRARY_PATH); - // envMap.put("PATH", Tools.DIR_HOME_JRE + "/bin:" + Os.getenv("PATH")); - - File customEnvFile = new File(Tools.DIR_GAME_NEW, "custom_env.txt"); - if (customEnvFile.exists() && customEnvFile.isFile()) { - BufferedReader reader = new BufferedReader(new FileReader(customEnvFile)); - String line; - while ((line = reader.readLine()) != null) { - // Not use split() as only split first one - int index = line.indexOf("="); - envMap.put(line.substring(0, index), line.substring(index + 1)); - } - reader.close(); - } - - for (Map.Entry env : envMap.entrySet()) { - setenv(env.getKey(), env.getValue(), true); - } - - setLdLibraryPath(LD_LIBRARY_PATH); - - // return ldLibraryPath; - } - - public static native int chdir(String path); - public static native boolean dlopen(String libPath); - public static native void redirectLogcat(String path); - public static native void setLdLibraryPath(String ldLibraryPath); public static native void saveGLContext(); - public static native void setenv(String key, String value, boolean overwrite); - - // Obtain AWT screen pixels to render on Android SurfaceView - public static native int[] renderAWTScreenFrame(/* Object canvas, int width, int height */); static { System.loadLibrary("pojavexec"); diff --git a/Natives/CMakeLists.txt b/Natives/CMakeLists.txt index 55ef2fb4..1367bf12 100644 --- a/Natives/CMakeLists.txt +++ b/Natives/CMakeLists.txt @@ -1,19 +1,33 @@ cmake_minimum_required(VERSION 3.6) project(PojavLauncher) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon -fobjc-arc -ObjC -I'${CMAKE_CURRENT_LIST_DIR}/resources/Frameworks/MetalANGLE.framework/Headers'") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon -fobjc-arc -ObjC -I'${CMAKE_CURRENT_LIST_DIR}/resources/Frameworks/MetalANGLE.framework/Headers' -I'${CMAKE_CURRENT_LIST_DIR}/external/DBNumberedSlider/Classes'" +) + set(CMAKE_SHARED_LINKER_FLAGS "'${CMAKE_SHARED_LINKER_FLAGS}' -rpath @executable_path/Frameworks -rpath @loader_path/Frameworks") -add_executable(PojavLauncher main.m log.m JavaLauncher.m) -target_link_libraries(PojavLauncher - "-framework UIKit" -) -set_target_properties(PojavLauncher PROPERTIES - MACOSX_BUNDLE TRUE - MACOSX_FRAMEWORK_IDENTIFIER org.cmake.ExecutableTarget - MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_LIST_DIR}/Info.plist") +set(CMAKE_EXE_LINKER_FLAGS "'${CMAKE_EXE_LINKER_FLAGS}' -rpath @executable_path/Frameworks -rpath @loader_path/Frameworks") -add_library(pojavexec SHARED log.m AppDelegate.m SceneDelegate.m UILauncher.m LauncherViewController.m LauncherPreferencesViewController.m LauncherFAQViewController.m LoginViewController.m SurfaceViewController.m UpdateHistoryViewController.m AboutLauncherViewController.m ios_uikit_bridge.m customcontrols/ControlButton.m egl_bridge.m input_bridge_v3.m utils.m) +add_library(pojavexec SHARED + AboutLauncherViewController.m + AppDelegate.m + CustomControlsViewController.m + LauncherFAQViewController.m + LauncherPreferences.m + LauncherPreferencesViewController.m + LauncherViewController.m + LoginViewController.m + SceneDelegate.m + SurfaceViewController.m + UpdateHistoryViewController.m + customcontrols/ControlButton.m + egl_bridge.m + external/DBNumberedSlider/Classes/DBNumberedSlider.m + input_bridge_v3.m + ios_uikit_bridge.m + log.m + utils.m +) target_link_libraries(pojavexec "-F'${CMAKE_CURRENT_LIST_DIR}/resources/Frameworks'" "-framework UIKit" @@ -22,3 +36,16 @@ target_link_libraries(pojavexec "-framework AuthenticationServices" "-Wl,-undefined -Wl,dynamic_lookup" ) + +add_executable(PojavLauncher + main.m + log.m + JavaLauncher.m) +target_link_libraries(PojavLauncher + "-L'${CMAKE_CURRENT_LIST_DIR}/build'" + "-framework UIKit -lpojavexec" +) +set_target_properties(PojavLauncher PROPERTIES + MACOSX_BUNDLE TRUE + MACOSX_FRAMEWORK_IDENTIFIER org.cmake.ExecutableTarget + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_LIST_DIR}/Info.plist") diff --git a/Natives/CustomControlsViewController.h b/Natives/CustomControlsViewController.h new file mode 100644 index 00000000..697c574a --- /dev/null +++ b/Natives/CustomControlsViewController.h @@ -0,0 +1,5 @@ +#import + +@interface CustomControlsViewController : UIViewController + +@end diff --git a/Natives/CustomControlsViewController.m b/Natives/CustomControlsViewController.m new file mode 100644 index 00000000..d6acc394 --- /dev/null +++ b/Natives/CustomControlsViewController.m @@ -0,0 +1,58 @@ +#import "CustomControlsViewController.h" + +#include "utils.h" + +@interface CustomControlsViewController () { +} + +// - (void)method + +@end + +@implementation CustomControlsViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [self.navigationController setNavigationBarHidden:YES animated:YES]; + [self setNeedsUpdateOfScreenEdgesDeferringSystemGestures]; + [self setNeedsUpdateOfHomeIndicatorAutoHidden]; + + [self setTitle:@"Custom controls"]; + + CGRect screenBounds = [[UIScreen mainScreen] bounds]; + CGFloat screenScale = [[UIScreen mainScreen] scale]; + + int width = (int) roundf(screenBounds.size.width); + int height = (int) roundf(screenBounds.size.height); + + // Update color mode once + if(@available(iOS 13.0, *)) { + [self traitCollectionDidChange:nil]; + } else { + self.view.backgroundColor = [UIColor whiteColor]; + } + + +} + +- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures { + return UIRectEdgeBottom; +} + +- (BOOL)prefersHomeIndicatorAutoHidden { + return NO; +} + +-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { + if(@available(iOS 13.0, *)) { + if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { + self.view.backgroundColor = [UIColor blackColor]; + } else { + self.view.backgroundColor = [UIColor whiteColor]; + } + } +} + +@end diff --git a/Natives/JavaLauncher.h b/Natives/JavaLauncher.h index 0624e6b7..df52ab8d 100644 --- a/Natives/JavaLauncher.h +++ b/Natives/JavaLauncher.h @@ -5,4 +5,3 @@ static bool started = false; int launchJVM(int argc, char *argv[]); -int launchUI(int argc, char *argv[]); diff --git a/Natives/JavaLauncher.m b/Natives/JavaLauncher.m index 55704aab..2c01ef79 100644 --- a/Natives/JavaLauncher.m +++ b/Natives/JavaLauncher.m @@ -18,6 +18,8 @@ #include "utils.h" #include "JavaLauncher.h" +#import "LauncherPreferences.h" + // PojavLancher: fixme: are these wrong? #define FULL_VERSION "1.8.0-internal" #define DOT_VERSION "1.8" @@ -81,43 +83,55 @@ void init_loadCustomEnv() { } void init_loadCustomJvmFlags() { - char jvmargs[10000]; - FILE* argsFile = fopen(args_path, "r"); - debug("[Pre-init] Reading custom JVM args (overrideargs.txt), opened=%d\n", argsFile != NULL); - if (argsFile) { - if (!fgets(jvmargs, 10000, argsFile)) { - debug("[Pre-init] Warning: could not read overrideargs.txt"); - fclose(argsFile); - return; - } - char *pch; - pch = strtok(jvmargs, " "); - while (pch != NULL) { - margv[margc] = (char*)calloc(1, (strlen(pch)+1) * sizeof(char)); - strcpy(margv[margc], pch); - debug("[Pre-init] Added custom flag: %s", margv[margc]); - pch = strtok(NULL, " "); - ++margc; - } - fclose(argsFile); + NSString *jvmargs = getPreference(@"java_args"); + for (NSString *jvmarg in [jvmargs componentsSeparatedByString:@" -"]) { + if ([jvmarg length] == 0) continue; + margv[margc] = (char *) [jvmarg UTF8String]; + NSLog(@"[Pre-init] Added custom JVM flag: %@", jvmarg); + ++margc; + } +} + +void init_migrateToPlist(char* prefKey, char* filename) { + // NSString *readmeStr = @"#README - this file has been merged into launcher_preferences.plist"; + NSError *error; + NSString *str, *path_str; + + // overrideargs.txt + path_str = [NSString stringWithFormat:@"%s/%s", getenv("POJAV_HOME"), filename]; + str = [NSString stringWithContentsOfFile:path_str encoding:NSUTF8StringEncoding error:&error]; + if (error == nil && ![str hasPrefix:@"#README"]) { + setPreference(@(prefKey), str); + [@"#README - this file has been merged into launcher_preferences.plist" writeToFile:path_str atomically:YES encoding:NSUTF8StringEncoding error:nil]; } } int launchJVM(int argc, char *argv[]) { + char *homeDir; if (!started) { setenv("BUNDLE_PATH", dirname(argv[0]), 1); // Are we running on a jailbroken environment? if (strncmp(argv[0], "/Applications", 13) == 0) { setenv("HOME", "/var/mobile", 1); + homeDir = "/var/mobile/Documents/.pojavlauncher"; + } else { + char pojavHome[2048]; + sprintf(pojavHome, "%s/Documents", getenv("HOME")); + homeDir = (char *) pojavHome; } + setenv("POJAV_HOME", homeDir, 1); + } else { + homeDir = getenv("POJAV_HOME"); } - char* homeDir = getenv("HOME"); - sprintf((char*) args_path, "%s/Documents/.pojavlauncher/overrideargs.txt", homeDir); - sprintf((char*) env_path, "%s/Documents/.pojavlauncher/custom_env.txt", homeDir); - sprintf((char*) log_path, "%s/Documents/.pojavlauncher/latestlog.txt", homeDir); + loadPreferences(); + init_migrateToPlist("selected_version", "config_ver.txt"); + init_migrateToPlist("java_args", "overrideargs.txt"); + + sprintf((char*) env_path, "%s/custom_env.txt", homeDir); + sprintf((char*) log_path, "%s/latestlog.txt", homeDir); sprintf((char*) java_libs_path, "%s/libs", getenv("BUNDLE_PATH")); mkdir(dirname(log_path), 755); @@ -127,7 +141,7 @@ int launchJVM(int argc, char *argv[]) { // Redirect stdio to latestlog.txt int ret; char newname[2048]; - sprintf(newname, "%s/Documents/.pojavlauncher/latestlog.old.txt", homeDir); + sprintf(newname, "%s/latestlog.old.txt", homeDir); ret = rename(log_path, newname); FILE* logFile = fopen(log_path, "w"); if (!logFile) { @@ -143,6 +157,8 @@ int launchJVM(int argc, char *argv[]) { debug("[Pre-init] Beginning JVM launch\n"); // setenv("LIBGL_FB", "2", 1); setenv("LIBGL_MIPMAP", "3", 1); + + // Fix white color on banner and sheep, since GL4ES 1.1.5 setenv("LIBGL_NORMALIZE", "1", 1); init_loadCustomEnv(); @@ -160,7 +176,7 @@ int launchJVM(int argc, char *argv[]) { } char controlPath[2048]; - sprintf(controlPath, "%s/Documents/.pojavlauncher/controlmap", homeDir); + sprintf(controlPath, "%s/controlmap", homeDir); mkdir(controlPath, S_IRWXU | S_IRWXG | S_IRWXO); setenv("POJAV_PATH_CONTROL", controlPath, 1); @@ -190,8 +206,8 @@ int launchJVM(int argc, char *argv[]) { char *userHome = calloc(1, 2048); snprintf(frameworkPath, 2048, "-Djava.library.path=%s/Frameworks", getenv("BUNDLE_PATH")); snprintf(javaPath, 2048, "%s/bin/java", javaHome); - snprintf(userDir, 2048, "-Duser.dir=%s/Documents/minecraft", homeDir); - snprintf(userHome, 2048, "-Duser.home=%s/Documents", homeDir); + snprintf(userDir, 2048, "-Duser.dir=%s/Documents/minecraft", getenv("HOME")); + snprintf(userHome, 2048, "-Duser.home=%s/Documents", getenv("HOME")); chdir(userDir); @@ -285,11 +301,9 @@ int launchJVM(int argc, char *argv[]) { debug("[Init] Calling JLI_Launch"); -/* for (int i = 0; i < margc; i++) { debug("arg[%d] = %s", i, margv[i]); } -*/ int targc = started ? argc : margc; char **targv = started ? argv : margv; diff --git a/Natives/LauncherPreferences.h b/Natives/LauncherPreferences.h new file mode 100644 index 00000000..628d56b4 --- /dev/null +++ b/Natives/LauncherPreferences.h @@ -0,0 +1,5 @@ +#import + +void loadPreferences(); +id getPreference(NSString* key); +void setPreference(NSString* key, id value); diff --git a/Natives/LauncherPreferences.m b/Natives/LauncherPreferences.m new file mode 100644 index 00000000..42b3a4b0 --- /dev/null +++ b/Natives/LauncherPreferences.m @@ -0,0 +1,40 @@ +#import "LauncherPreferences.h" + +NSMutableDictionary *prefDict; +NSString* prefPath; + +void loadPreferences() { + prefPath = [@(getenv("POJAV_HOME")) + stringByAppendingPathComponent:@"launcher_preferences.plist"]; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + if (![fileManager fileExistsAtPath:prefPath]) { + prefDict = [[NSMutableDictionary alloc] init]; + prefDict[@"button_scale"] = @(100); + prefDict[@"selected_version"] = @"1.7.10"; + prefDict[@"vertype_release"] = @YES; + prefDict[@"vertype_snapshot"] = @NO; + prefDict[@"vertype_oldalpha"] = @NO; + prefDict[@"vertype_oldbeta"] = @NO; + prefDict[@"time_longPressTrigger"] = @(400); + prefDict[@"default_ctrl"] = @"default.json"; + prefDict[@"java_args"] = @""; + prefDict[@"custom_envVars"] = @""; // TODO + [prefDict writeToFile:prefPath atomically:YES]; + } else { + prefDict = [NSMutableDictionary dictionaryWithContentsOfFile:prefPath]; + } +} + +id getPreference(NSString* key) { + NSObject *object = prefDict[key]; + if (object == [NSNull null] || object == nil) { + NSLog(@"LauncherPreferences: %@ is NULL", key); + } + return object; +} + +void setPreference(NSString* key, id value) { + prefDict[key] = value; + [prefDict writeToFile:prefPath atomically:YES]; +} diff --git a/Natives/LauncherPreferencesViewController.m b/Natives/LauncherPreferencesViewController.m index 0a7af8bf..b331b8d9 100644 --- a/Natives/LauncherPreferencesViewController.m +++ b/Natives/LauncherPreferencesViewController.m @@ -1,3 +1,5 @@ +#import "DBNumberedSlider.h" +#import "LauncherPreferences.h" #import "LauncherPreferencesViewController.h" #include "utils.h" @@ -39,27 +41,40 @@ UITextField* versionTextField; self.view.backgroundColor = [UIColor whiteColor]; } -// not yet finished, empty view controller for now -/* - UILabel *btnsizeTextView = [[UILabel alloc] initWithFrame:CGRectMake(4.0, 4.0, 0.0, 30.0)]; - btnsizeTextView.text = @"Button size: "; + UILabel *btnsizeTextView = [[UILabel alloc] initWithFrame:CGRectMake(4.0, 8.0, 0.0, 30.0)]; + btnsizeTextView.text = @"Button scale: "; btnsizeTextView.numberOfLines = 0; + btnsizeTextView.textAlignment = NSTextAlignmentCenter; [btnsizeTextView sizeToFit]; + CGRect tempRect = btnsizeTextView.frame; + tempRect.size.height = 30.0; + btnsizeTextView.frame = tempRect; + [scrollView addSubview:btnsizeTextView]; - UISlider *buttonSizeSlider = [[UISlider alloc] initWithFrame:CGRectMake(8.0 + btnsizeTextView.frame.x, 4.0, 200.0, 30.0)]; - // [buttonSizeSlider addTarget:self action:@selector(sliderAction:) forControlEvents:UIControlEventValueChanged]; + DBNumberedSlider *buttonSizeSlider = [[DBNumberedSlider alloc] initWithFrame:CGRectMake(8.0 + btnsizeTextView.frame.size.width, 8.0, self.view.frame.size.width - 8.0 + btnsizeTextView.frame.origin.x, btnsizeTextView.frame.size.height)]; + buttonSizeSlider.tag = 1; + [buttonSizeSlider addTarget:self action:@selector(sliderMoved:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside]; [buttonSizeSlider setBackgroundColor:[UIColor clearColor]]; buttonSizeSlider.minimumValue = 50.0; buttonSizeSlider.maximumValue = 200.0; buttonSizeSlider.continuous = YES; - buttonSizeSlider.value = 50.0; + buttonSizeSlider.value = ((NSNumber *) getPreference(@"button_scale")).floatValue; [scrollView addSubview:buttonSizeSlider]; -*/ scrollView.contentSize = CGSizeMake(scrollView.frame.size.width, scrollView.frame.size.height + 200); } +- (void)sliderMoved:(DBNumberedSlider *)sender { + switch (sender.tag) { + case 1: + setPreference(@"button_scale", @(sender.value)); + break; + default: + NSLog(@"what does slider %ld for? implement me!", sender.tag); + break; + } +} - (UIRectEdge)preferredScreenEdgesDeferringSystemGestures { return UIRectEdgeBottom; diff --git a/Natives/LauncherViewController.m b/Natives/LauncherViewController.m index 019c7081..eda1ba58 100644 --- a/Natives/LauncherViewController.m +++ b/Natives/LauncherViewController.m @@ -1,5 +1,7 @@ -#import "LauncherViewController.h" +#import "CustomControlsViewController.h" +#import "LauncherPreferences.h" #import "LauncherPreferencesViewController.h" +#import "LauncherViewController.h" #include "utils.h" @@ -12,8 +14,6 @@ @implementation LauncherViewController -NSString* configver_path; - NSArray* versionList; UIPickerView* versionPickerView; UITextField* versionTextField; @@ -45,13 +45,6 @@ int versionSelectedAt = 0; self.view.backgroundColor = [UIColor whiteColor]; } - NSError *error; - configver_path = [NSString stringWithFormat:@"%s/Documents/.pojavlauncher/config_ver.txt", getenv("HOME")]; - NSString *configver = [NSString stringWithContentsOfFile:configver_path encoding:NSUTF8StringEncoding error:&error]; - if (error) { - NSLog(@"Error: could not read config_ver.txt: %@", error.localizedDescription); - } - UILabel *versionTextView = [[UILabel alloc] initWithFrame:CGRectMake(4.0, 4.0, 0.0, 0.0)]; versionTextView.text = @"Minecraft version: "; versionTextView.numberOfLines = 0; @@ -61,7 +54,7 @@ int versionSelectedAt = 0; versionTextField = [[UITextField alloc] initWithFrame:CGRectMake(versionTextView.bounds.size.width + 4.0, 4.0, width - versionTextView.bounds.size.width - 8.0, height - 58.0)]; [versionTextField addTarget:versionTextField action:@selector(resignFirstResponder) forControlEvents:UIControlEventEditingDidEndOnExit]; versionTextField.placeholder = @"Specify version..."; - versionTextField.text = configver; + versionTextField.text = (NSString *) getPreference(@"selected_version"); versionTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentTop; versionTextField.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; @@ -79,7 +72,10 @@ int versionSelectedAt = 0; [scrollView addSubview:versionTextField]; - self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Settings" style:UIBarButtonItemStyleDone target:self action:@selector(enterPreferences)]; + self.navigationItem.rightBarButtonItems = @[ + [[UIBarButtonItem alloc] initWithTitle:@"Custom controls" style:UIBarButtonItemStyleDone target:self action:@selector(enterCustomControls)], + [[UIBarButtonItem alloc] initWithTitle:@"Settings" style:UIBarButtonItemStyleDone target:self action:@selector(enterPreferences)] + ]; install_progress_bar = [[UIProgressView alloc] initWithFrame:CGRectMake(4.0, height - 58.0, width - 8.0, 6.0)]; [scrollView addSubview:install_progress_bar]; @@ -185,6 +181,11 @@ int versionSelectedAt = 0; } #pragma mark - Button click events +- (void)enterCustomControls { + CustomControlsViewController *vc = [[CustomControlsViewController alloc] init]; + [self.navigationController pushViewController:vc animated:YES]; +} + - (void)enterPreferences { LauncherPreferencesViewController *vc = [[LauncherPreferencesViewController alloc] init]; [self.navigationController pushViewController:vc animated:YES]; @@ -207,7 +208,7 @@ int versionSelectedAt = 0; #pragma mark - UIPickerView stuff - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { versionTextField.text = [self pickerView:pickerView titleForRow:row forComponent:component]; - [versionTextField.text writeToFile:configver_path atomically:NO encoding:NSUTF8StringEncoding error:nil]; + setPreference(@"selected_version", versionTextField.text); } - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView { diff --git a/Natives/LoginViewController.m b/Natives/LoginViewController.m index c19720a5..e922dcdb 100644 --- a/Natives/LoginViewController.m +++ b/Natives/LoginViewController.m @@ -384,7 +384,7 @@ NSMutableArray *accountList; DIR *d; struct dirent *dir; char accPath[2048]; - sprintf(accPath, "%s/Documents/.pojavlauncher/accounts", getenv("HOME")); + sprintf(accPath, "%s/accounts", getenv("POJAV_HOME")); d = opendir(accPath); if (d) { int i = 0; @@ -438,7 +438,7 @@ NSMutableArray *accountList; if (editingStyle == UITableViewCellEditingStyleDelete) { NSString *str = [accountList objectAtIndex:indexPath.row]; char accPath[2048]; - sprintf(accPath, "%s/Documents/.pojavlauncher/accounts/%s.json", getenv("HOME"), [str UTF8String]); + sprintf(accPath, "%s/accounts/%s.json", getenv("POJAV_HOME"), [str UTF8String]); remove(accPath); [accountList removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; diff --git a/Natives/SurfaceViewController.m b/Natives/SurfaceViewController.m index bfe4eefc..bb06adb6 100644 --- a/Natives/SurfaceViewController.m +++ b/Natives/SurfaceViewController.m @@ -1,3 +1,4 @@ +#import "LauncherPreferences.h" #import "SurfaceViewController.h" #import "egl_bridge.h" #import "ios_uikit_bridge.h" @@ -94,7 +95,7 @@ int notchOffset; [touchView addGestureRecognizer:tapGesture]; UILongPressGestureRecognizer *longpressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(surfaceOnLongpress:)]; - longpressGesture.minimumPressDuration = 0.4; + longpressGesture.minimumPressDuration = ((NSNumber *)getPreference(@"time_longPressTrigger")).floatValue / 1000; [touchView addGestureRecognizer:longpressGesture]; [self.view addSubview:touchView]; @@ -111,9 +112,10 @@ int notchOffset; [touchView addGestureRecognizer:mouseWheelGesture]; } - CGFloat rectBtnWidth = 80.0; - CGFloat rectBtnHeight = 30.0; - CGFloat squareBtnSize = 50.0; + CGFloat buttonScale = ((NSNumber *) getPreference(@"button_scale")).floatValue / 100.0; + CGFloat rectBtnWidth = 80.0 * buttonScale; + CGFloat rectBtnHeight = 30.0 * buttonScale; + CGFloat squareBtnSize = 50.0 * buttonScale; #ifndef DEBUG_VISIBLE_TEXT_FIELD inputView = [[UITextField alloc] initWithFrame:CGRectMake(5 * 3 + rectBtnWidth * 2, 5, rectBtnWidth, rectBtnHeight)]; @@ -136,30 +138,16 @@ int notchOffset; // Temporary fallback controls BOOL cc_fallback = YES; - - char controlFilePath[2048]; - sprintf(controlFilePath, "%s/default.json", getenv("POJAV_PATH_CONTROL")); - FILE *cc_file = fopen(controlFilePath, "r"); - // 100kb (might not safe) - char cc_data[102400]; - long cc_size; - if (cc_file) { - fseek(cc_file, 0L, SEEK_END); - cc_size = ftell(cc_file); - rewind(cc_file); - } + NSString *controlFilePath = [NSString stringWithFormat:@"%s/%@", getenv("POJAV_PATH_CONTROL"), (NSString *)getPreference(@"default_ctrl")]; NSError *cc_error; - if (cc_size > 102400) { - NSLog(@"Error: control data is too big (over 100kb)."); - fclose(cc_file); - } else if (!cc_file || !fread(cc_data, cc_size, 1, cc_file)) { - NSLog(@"Error: could not read \"default.json\", falling back to default control, error: %s", strerror(errno)); - fclose(cc_file); + NSString *cc_data = [NSString stringWithContentsOfFile:controlFilePath encoding:NSUTF8StringEncoding error:&cc_error]; + + if (cc_error != nil) { + NSLog(@"Error: could not read \"%@\", falling back to default control, error: %@", controlFilePath, cc_error.localizedDescription); } else { - fclose(cc_file); - NSData* cc_objc_data = [@(cc_data) dataUsingEncoding:NSUTF8StringEncoding]; + NSData* cc_objc_data = [cc_data dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *cc_dictionary = [NSJSONSerialization JSONObjectWithData:cc_objc_data options:kNilOptions error:&cc_error]; if (cc_error != nil) { showDialog(self, @"Error parsing JSON", cc_error.localizedDescription); @@ -180,11 +168,11 @@ int notchOffset; } if (cc_fallback == YES) { - ADD_BUTTON(@"GUI", SPECIALBTN_TOGGLECTRL, CGRectMake(5, height - 5 - 50, squareBtnSize, squareBtnSize), NO); + ADD_BUTTON(@"GUI", SPECIALBTN_TOGGLECTRL, CGRectMake(5, height - 5 - squareBtnSize, squareBtnSize, squareBtnSize), NO); ADD_BUTTON(@"Keyboard", SPECIALBTN_KEYBOARD, CGRectMake(5 * 3 + rectBtnWidth * 2, 5, rectBtnWidth, rectBtnHeight), YES); - ADD_BUTTON(@"Pri", SPECIALBTN_MOUSEPRI, CGRectMake(5, height - 5 * 3 - 50 * 3, squareBtnSize, squareBtnSize), YES); - ADD_BUTTON(@"Sec", SPECIALBTN_MOUSESEC, CGRectMake(5 * 3 + 50 * 2, height - 5 * 3 - 50 * 3, squareBtnSize, squareBtnSize), YES); + ADD_BUTTON(@"Pri", SPECIALBTN_MOUSEPRI, CGRectMake(5, height - 5 * 3 - squareBtnSize * 3, squareBtnSize, squareBtnSize), YES); + ADD_BUTTON(@"Sec", SPECIALBTN_MOUSESEC, CGRectMake(5 * 3 + squareBtnSize * 2, height - 5 * 3 - squareBtnSize * 3, squareBtnSize, squareBtnSize), YES); ADD_BUTTON(@"Debug", GLFW_KEY_F3, CGRectMake(5, 5, rectBtnWidth, rectBtnHeight), YES); ADD_BUTTON(@"Chat", GLFW_KEY_T, CGRectMake(5 * 2 + rectBtnWidth, 5, rectBtnWidth, rectBtnHeight), YES); @@ -193,14 +181,14 @@ int notchOffset; ADD_BUTTON(@"Offhand", GLFW_KEY_F, CGRectMake(5 * 6 + rectBtnWidth * 5, 5, rectBtnWidth, rectBtnHeight), YES); ADD_BUTTON(@"3rd", GLFW_KEY_F5, CGRectMake(5, 5 * 2 + rectBtnHeight, rectBtnWidth, rectBtnHeight), YES); - ADD_BUTTON(@"▲", GLFW_KEY_W, CGRectMake(5 * 2 + 50, height - 5 * 3 - 50 * 3, squareBtnSize, squareBtnSize), YES); - ADD_BUTTON(@"◀", GLFW_KEY_A, CGRectMake(5, height - 5 * 2 - 50 * 2, squareBtnSize, squareBtnSize), YES); - ADD_BUTTON(@"▼", GLFW_KEY_S, CGRectMake(5 * 2 + 50, height - 5 - 50, squareBtnSize, squareBtnSize), YES); - ADD_BUTTON(@"▶", GLFW_KEY_D, CGRectMake(5 * 3 + 50 * 2, height - 5 * 2 - 50 * 2, squareBtnSize, squareBtnSize), YES); - ADD_BUTTON(@"◇", GLFW_KEY_LEFT_SHIFT, CGRectMake(5 * 2 + 50, height - 5 * 2 - 50 * 2, squareBtnSize, squareBtnSize), YES); - ADD_BUTTON(@"Inv", GLFW_KEY_E, CGRectMake(5 * 3 + 50 * 2, height - 5 - 50, squareBtnSize, squareBtnSize), YES); + ADD_BUTTON(@"▲", GLFW_KEY_W, CGRectMake(5 * 2 + squareBtnSize, height - 5 * 3 - squareBtnSize * 3, squareBtnSize, squareBtnSize), YES); + ADD_BUTTON(@"◀", GLFW_KEY_A, CGRectMake(5, height - 5 * 2 - squareBtnSize * 2, squareBtnSize, squareBtnSize), YES); + ADD_BUTTON(@"▼", GLFW_KEY_S, CGRectMake(5 * 2 + squareBtnSize, height - 5 - squareBtnSize, squareBtnSize, squareBtnSize), YES); + ADD_BUTTON(@"▶", GLFW_KEY_D, CGRectMake(5 * 3 + squareBtnSize * 2, height - 5 * 2 - squareBtnSize * 2, squareBtnSize, squareBtnSize), YES); + ADD_BUTTON(@"◇", GLFW_KEY_LEFT_SHIFT, CGRectMake(5 * 2 + squareBtnSize, height - 5 * 2 - squareBtnSize * 2, squareBtnSize, squareBtnSize), YES); + ADD_BUTTON(@"Inv", GLFW_KEY_E, CGRectMake(5 * 3 + squareBtnSize * 2, height - 5 - squareBtnSize, squareBtnSize, squareBtnSize), YES); - ADD_BUTTON(@"⬛", GLFW_KEY_SPACE, CGRectMake(width - 5 * 2 - 50 * 2, height - 5 * 2 - 50 * 2, squareBtnSize, squareBtnSize), YES); + ADD_BUTTON(@"⬛", GLFW_KEY_SPACE, CGRectMake(width - 5 * 2 - squareBtnSize * 2, height - 5 * 2 - squareBtnSize * 2, squareBtnSize, squareBtnSize), YES); ADD_BUTTON(@"Esc", GLFW_KEY_ESCAPE, CGRectMake(width - 5 - rectBtnWidth, height - 5 - rectBtnHeight, rectBtnWidth, rectBtnHeight), YES); diff --git a/Natives/UILauncher.m b/Natives/UILauncher.m deleted file mode 100644 index 3623008e..00000000 --- a/Natives/UILauncher.m +++ /dev/null @@ -1,14 +0,0 @@ -// -// main.m -// - -#import -#import "AppDelegate.h" - -#include "JavaLauncher.h" - -int launchUI(int argc, char *argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/Natives/external/DBNumberedSlider b/Natives/external/DBNumberedSlider new file mode 160000 index 00000000..bc6ea603 --- /dev/null +++ b/Natives/external/DBNumberedSlider @@ -0,0 +1 @@ +Subproject commit bc6ea60353efd2e741de81f84aa691441f2d0ca9 diff --git a/Natives/input_bridge_v3.m b/Natives/input_bridge_v3.m index 892437fc..fad37a48 100644 --- a/Natives/input_bridge_v3.m +++ b/Natives/input_bridge_v3.m @@ -9,14 +9,16 @@ * TODO: * - Implements glfwSetCursorPos() to handle grab camera pos correctly. */ - -#include "jni.h" + +#import +#import "AppDelegate.h" + #include #include +#include "jni.h" #include "glfw_keycodes.h" #include "ios_uikit_bridge.h" - #include "log.h" #include "utils.h" @@ -264,7 +266,10 @@ JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_uikit_UIKit_runOnUIThread(JNIEnv JNIEXPORT jint JNICALL Java_net_kdt_pojavlaunch_uikit_UIKit_launchUI(JNIEnv* env, jclass clazz, jobjectArray args) { int argc = (*env)->GetArrayLength(env, args); char **argv = convert_to_char_array(env, args); - return launchUI(argc, argv); + + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } } JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeAttachThreadToOther(JNIEnv* env, jclass clazz, jboolean isAndroid, jboolean isUseStackQueueBool) { diff --git a/Natives/ios_uikit_bridge.m b/Natives/ios_uikit_bridge.m index 298bdd06..6a13a826 100644 --- a/Natives/ios_uikit_bridge.m +++ b/Natives/ios_uikit_bridge.m @@ -134,7 +134,7 @@ void UIKit_launchMinecraftSurfaceVC() { if (@available(iOS 13.0, *)) { rootController = UIApplication.sharedApplication.windows.lastObject.rootViewController; } else { - rootController =(UIViewController*) [[(AppDelegate*) [[UIApplication sharedApplication]delegate] window] rootViewController]; + rootController = (UIViewController*) [[(AppDelegate*) [[UIApplication sharedApplication]delegate] window] rootViewController]; } UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MinecraftSurface" bundle:nil]; diff --git a/README.md b/README.md index 9004f568..597bb211 100644 --- a/README.md +++ b/README.md @@ -61,15 +61,16 @@ PojavLauncher is amazing, and surprisingly stable, and it wouldn't be this way w @genericrandom64 ## Third party components and their licenses -- [Apache Commons](https://commons.apache.org): [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt). +- [Caciocavallo](https://github.com/PojavLauncherTeam/caciocavallo): [GNU GPLv2 License](https://github.com/PojavLauncherTeam/caciocavallo/blob/master/LICENSE). - [jsr305](https://code.google.com/p/jsr-305): [3-Clause BSD License](http://opensource.org/licenses/BSD-3-Clause). - [org.json](https://github.com/stleary/JSON-java): [The JSON License](https://www.json.org/license.html). -- [Boardwalk](https://github.com/zhuowei/Boardwalk) (JVM Launcher): [Apache License 2.0](https://github.com/zhuowei/Boardwalk/blob/master/LICENSE) +- [Boardwalk](https://github.com/zhuowei/Boardwalk): [Apache 2.0 License](https://github.com/zhuowei/Boardwalk/blob/master/LICENSE) - [GL4ES](https://github.com/ptitSeb/gl4es) by @lunixbochs @ptitSeb: [MIT License](https://github.com/ptitSeb/gl4es/blob/master/LICENSE). -- [MetalANGLE](https://github.com/kakashidinho/metalangle) by @kakashidinho and ANGLE team: [BSD License 2.0](https://github.com/kakashidinho/metalangle/blob/master/LICENSE). +- [MetalANGLE](https://github.com/kakashidinho/metalangle) by @kakashidinho and ANGLE team: [BSD 2.0 License](https://github.com/kakashidinho/metalangle/blob/master/LICENSE). - [OpenJDK 16](https://www.ios-repo-updates.com/repository/procursus/package/openjdk-16-jre) ported to iOS by @Diatrus: [GNU GPLv2 License](https://openjdk.java.net/legal/gplv2+ce.html). - [LWJGL3](https://github.com/PojavLauncherTeam/lwjgl3): [BSD-3 License](https://github.com/LWJGL/lwjgl3/blob/master/LICENSE.md). - [LWJGLX](https://github.com/PojavLauncherTeam/lwjglx) (LWJGL2 API compatibility layer for LWJGL3): unknown license. +- [DBNumberedSlider](https://github.com/immago/DBNumberedSlider): [Apache 2.0 License](https://github.com/immago/DBNumberedSlider/blob/master/LICENSE)