diff --git a/app_pojavlauncher/src/main/assets/rt4.jar b/app_pojavlauncher/src/main/assets/rt4.jar index 22a89a25e..a9de508d4 100644 Binary files a/app_pojavlauncher/src/main/assets/rt4.jar and b/app_pojavlauncher/src/main/assets/rt4.jar differ diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/DummyLauncher.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/DummyLauncher.java index ac50360b8..38bcf5720 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/DummyLauncher.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/DummyLauncher.java @@ -59,21 +59,13 @@ public class DummyLauncher extends BaseActivity { mProgressLayout.observe(ProgressLayout.INSTALL_MODPACK); playHD.setOnClickListener(view -> { - Log.i("downthecrop","hello from play HD touch"); - if(mProgressLayout.hasProcesses()){ - Toast.makeText(this, R.string.tasks_ongoing, Toast.LENGTH_LONG).show(); - return; - } + if(!runtimeReady()) return; Intent intent = new Intent(DummyLauncher.this, MainActivity.class); startActivity(intent); }); playSD.setOnClickListener(view -> { - Log.i("downthecrop","hello from play SD touch"); - if(mProgressLayout.hasProcesses()){ - Toast.makeText(this, R.string.tasks_ongoing, Toast.LENGTH_LONG).show(); - return; - } + if(!runtimeReady()) return; Intent intent = new Intent(DummyLauncher.this, JavaGUILauncherActivity.class); startActivity(intent); }); @@ -81,6 +73,13 @@ public class DummyLauncher extends BaseActivity { } + private boolean runtimeReady(){ + if(mProgressLayout.hasProcesses()){ + Toast.makeText(this, R.string.tasks_ongoing, Toast.LENGTH_LONG).show(); + return false; + } + return true; + } @SuppressLint("ClickableViewAccessibility") private void showBottomDialog() { @@ -88,69 +87,6 @@ public class DummyLauncher extends BaseActivity { dialog.show(getSupportFragmentManager(), "tag"); } - private void showFileChooser(int requestCode) { - Intent intent = new Intent(Intent.ACTION_GET_CONTENT); - - switch(requestCode){ - case FILE_SELECT_CODE_JSON: - intent.setType("application/json"); - intent.addCategory(Intent.CATEGORY_OPENABLE); - break; - case FILE_SELECT_CODE_ZIP: - intent.setType("application/zip"); - intent.addCategory(Intent.CATEGORY_OPENABLE); - break; - default: - intent.setType("*/*"); - intent.addCategory(Intent.CATEGORY_OPENABLE); - } - - - - try { - startActivityForResult( - Intent.createChooser(intent, "Select a File to Upload"), - requestCode); - } catch (android.content.ActivityNotFoundException ex) { - // Potentially direct the user to the Market with a Dialog - Toast.makeText(this, "Please install a File Manager.", - Toast.LENGTH_SHORT).show(); - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == FILE_SELECT_CODE_JSON) { - if (resultCode == RESULT_OK) { - Uri uri = data.getData(); - - // TODO: Change destination based on file type - File config = new File(Tools.DIR_DATA, "config.json"); - try { - Log.d("TAG", "Starting copy: " + uri.getPath()); - InputStream inputStream = getContentResolver().openInputStream(uri); - FileOutputStream fileOutputStream = new FileOutputStream(config); - byte buf[] = new byte[1024]; - int len; - while ((len = inputStream.read(buf)) > 0) { - fileOutputStream.write(buf, 0, len); - } - - Toast.makeText(this, "Config loaded. Please restart the app.", - Toast.LENGTH_SHORT).show(); - - fileOutputStream.close(); - inputStream.close(); - - // TODO: unzip the plugin here - } catch (IOException e1) { - Log.d("error", "Error with file " + e1); - } - } - } - super.onActivityResult(requestCode, resultCode, data); - } - @Override protected void onDestroy() { super.onDestroy(); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java index 775995ef7..3ae53bef6 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java @@ -4,13 +4,16 @@ import static net.kdt.pojavlaunch.MainActivity.fullyExit; import android.annotation.SuppressLint; import android.content.ClipboardManager; +import android.content.Context; import android.os.Bundle; import android.util.Log; import android.view.GestureDetector; import android.view.KeyEvent; import android.view.MotionEvent; +import android.view.ScaleGestureDetector; import android.view.View; import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.Toast; @@ -36,7 +39,6 @@ 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; @@ -50,9 +52,12 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc private LinearLayout mTouchPad; private ImageView mMousePointerImageView; private GestureDetector mGestureDetector; - + private boolean cameraMode = false; + private long lastPress = 0; + private ScaleGestureDetector scaleGestureDetector; + private boolean rcState = false; private boolean mSkipDetectMod, mIsVirtualMouseEnabled; - + @SuppressLint("ClickableViewAccessibility") @Override protected void onCreate(Bundle savedInstanceState) { @@ -71,21 +76,20 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc mTouchCharInput = findViewById(R.id.awt_touch_char); mTouchCharInput.setCharacterSender(new AwtCharSender()); + findViewById(R.id.mouseMode).setOnTouchListener(this); + findViewById(R.id.keyboard).setOnTouchListener(this); + findViewById(R.id.camera).setOnTouchListener(this); + findViewById(R.id.mb2).setOnTouchListener(this); + mTouchPad = findViewById(R.id.main_touchpad); mLoggerView = findViewById(R.id.launcherLoggerView); mMousePointerImageView = findViewById(R.id.main_mouse_pointer); mTextureView = findViewById(R.id.installmod_surfaceview); + scaleGestureDetector = new ScaleGestureDetector(this, new ScaleListener()); mGestureDetector = new GestureDetector(this, new SingleTapConfirm()); mTouchPad.setFocusable(false); mTouchPad.setVisibility(View.GONE); - findViewById(R.id.installmod_mouse_pri).setOnTouchListener(this); - findViewById(R.id.installmod_mouse_sec).setOnTouchListener(this); - findViewById(R.id.installmod_window_moveup).setOnTouchListener(this); - findViewById(R.id.installmod_window_movedown).setOnTouchListener(this); - findViewById(R.id.installmod_window_moveleft).setOnTouchListener(this); - findViewById(R.id.installmod_window_moveright).setOnTouchListener(this); - mMousePointerImageView.post(() -> { ViewGroup.LayoutParams params = mMousePointerImageView.getLayoutParams(); params.width = (int) (36 / 100f * LauncherPreferences.PREF_MOUSESCALE); @@ -96,6 +100,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc float prevX = 0, prevY = 0; @Override public boolean onTouch(View v, MotionEvent event) { + scaleGestureDetector.onTouchEvent(event); // MotionEvent reports input details from the touch screen // and other input controls. In this case, you are only // interested in events where the touch position changed. @@ -200,48 +205,59 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc decorView.setSystemUiVisibility(uiOptions); } + public static class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { + @Override + public boolean onScale(ScaleGestureDetector detector) { + float scaleFactor = detector.getScaleFactor(); + if (scaleFactor > 1) { //Send F4 To Zoom Out + AWTInputBridge.sendKey((char)AWTInputEvent.VK_F3, AWTInputEvent.VK_F3); + } else { //116 F3 To Zoom In + AWTInputBridge.sendKey((char)AWTInputEvent.VK_F4,AWTInputEvent.VK_F4); + } + return true; + } + @Override + public boolean onScaleBegin(ScaleGestureDetector detector) { + return true; + } + + @Override + public void onScaleEnd(ScaleGestureDetector detector) { + + } + } - @SuppressLint("ClickableViewAccessibility") @Override - public boolean onTouch(View v, MotionEvent e) { - boolean isDown; - switch (e.getActionMasked()) { - case MotionEvent.ACTION_DOWN: // 0 - case MotionEvent.ACTION_POINTER_DOWN: // 5 - isDown = true; - break; - case MotionEvent.ACTION_UP: // 1 - case MotionEvent.ACTION_CANCEL: // 3 - case MotionEvent.ACTION_POINTER_UP: // 6 - isDown = false; - break; - default: - return false; - } - - switch (v.getId()) { - case R.id.installmod_mouse_pri: - AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK, isDown); - break; - - case R.id.installmod_mouse_sec: - AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON3_DOWN_MASK, isDown); - break; - } - if(isDown) switch(v.getId()) { - case R.id.installmod_window_moveup: - AWTInputBridge.nativeMoveWindow(0, -10); - break; - case R.id.installmod_window_movedown: - AWTInputBridge.nativeMoveWindow(0, 10); - break; - case R.id.installmod_window_moveleft: - AWTInputBridge.nativeMoveWindow(-10, 0); - break; - case R.id.installmod_window_moveright: - AWTInputBridge.nativeMoveWindow(10, 0); - break; + public boolean onTouch(View v, MotionEvent e) { // these AWTInputEvent doesn't work for some reason + long time = System.currentTimeMillis(); + if (time > lastPress + 500) { + switch (v.getId()) { + case R.id.keyboard: + toggleKeyboard(this.getCurrentFocus()); + break; + case R.id.mb2: + if (!rcState) { + activateRC(); // Send F11 to activate RightClick + } else { + clearRC(); // Send F10 to clear RightClick + } + break; + case R.id.camera: + AWTInputBridge.sendKey((char) AWTInputEvent.VK_F9, AWTInputEvent.VK_F9); + if (!cameraMode) { // Camera Mode On + Log.i("downthecrop", "Hello from the camrea Button"); + //AWTInputBridge.sendKey((char) AWTInputEvent.VK_F9, AWTInputEvent.VK_F9); // Send F9 + cameraMode = true; + } else { // Camera Mode off + AWTInputBridge.sendKey((char) AWTInputEvent.VK_F8, AWTInputEvent.VK_F8); + cameraMode = false; + } + break; + case R.id.mouseMode: + toggleVirtualMouse(this.getCurrentFocus()); + } + lastPress = time; } return true; } @@ -259,6 +275,16 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc mMousePointerImageView.setY(y); } + private void clearRC(){ + rcState = false; + AWTInputBridge.sendKey((char)AWTInputEvent.VK_F10,AWTInputEvent.VK_F10); + } + + private void activateRC(){ + rcState = true; + AWTInputBridge.sendKey((char)AWTInputEvent.VK_F11,AWTInputEvent.VK_F11); + } + @SuppressWarnings("SuspiciousNameCombination") void sendScaledMousePosition(float x, float y){ // Clamp positions to the borders of the usable view, then scale them @@ -271,10 +297,6 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc ); } - public void forceClose(View v) { - MainActivity.dialogForceClose(this); - } - public void openLogOutput(View v) { mLoggerView.setVisibility(View.VISIBLE); } @@ -309,61 +331,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc return -1; } } - - - - private int doCustomInstall(Runtime runtime, File modFile, String javaArgs) { - mSkipDetectMod = true; - return launchJavaRuntime(runtime, javaArgs); - } - public void toggleKeyboard(View view) { mTouchCharInput.switchKeyboardState(); } - public void performCopy(View view) { - AWTInputBridge.sendKey(' ', AWTInputEvent.VK_CONTROL, 1); - AWTInputBridge.sendKey(' ', AWTInputEvent.VK_C); - AWTInputBridge.sendKey(' ', AWTInputEvent.VK_CONTROL, 0); - } - - public void performPaste(View view) { - AWTInputBridge.sendKey(' ', AWTInputEvent.VK_CONTROL, 1); - AWTInputBridge.sendKey(' ', AWTInputEvent.VK_V); - AWTInputBridge.sendKey(' ', AWTInputEvent.VK_CONTROL, 0); - } - - public int getJavaVersion(File modFile) { - try (ZipFile zipFile = new ZipFile(modFile)){ - ZipEntry manifest = zipFile.getEntry("META-INF/MANIFEST.MF"); - if(manifest == null) return -1; - - String manifestString = Tools.read(zipFile.getInputStream(manifest)); - String mainClass = Tools.extractUntilCharacter(manifestString, "Main-Class:", '\n'); - if(mainClass == null) return -1; - - mainClass = mainClass.trim().replace('.', '/') + ".class"; - ZipEntry mainClassFile = zipFile.getEntry(mainClass); - if(mainClassFile == null) return -1; - - InputStream classStream = zipFile.getInputStream(mainClassFile); - byte[] bytesWeNeed = new byte[8]; - int readCount = classStream.read(bytesWeNeed); - classStream.close(); - if(readCount < 8) return -1; - - ByteBuffer byteBuffer = ByteBuffer.wrap(bytesWeNeed); - if(byteBuffer.getInt() != 0xCAFEBABE) return -1; - short minorVersion = byteBuffer.getShort(); - short majorVersion = byteBuffer.getShort(); - Log.i("JavaGUILauncher", majorVersion+","+minorVersion); - return classVersionToJavaVersion(majorVersion); - }catch (Exception e) { - e.printStackTrace(); - return -1; - } - } - public static int classVersionToJavaVersion(int majorVersion) { - if(majorVersion < 46) return 2; // there isn't even an arm64 port of jre 1.1 (or anything before 1.8 in fact) - return majorVersion - 44; - } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java index 89a521463..d1eb9bafc 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java @@ -286,7 +286,8 @@ public class LauncherActivity extends BaseActivity { @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - if (requestCode == REQUEST_STORAGE_REQUEST_CODE){ + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (requestCode == REQUEST_STORAGE_REQUEST_CODE) { synchronized (mLockStoragePerm) { mLockStoragePerm.notifyAll(); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MyDialogFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MyDialogFragment.java index e7aa16703..b0434ec5f 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MyDialogFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MyDialogFragment.java @@ -1,16 +1,26 @@ package net.kdt.pojavlaunch; +import static android.app.Activity.RESULT_OK; + +import android.annotation.SuppressLint; import android.app.Dialog; import android.content.Intent; +import android.database.Cursor; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; +import android.net.Uri; import android.os.Bundle; +import android.provider.OpenableColumns; import android.util.Log; +import android.util.TypedValue; import android.view.Gravity; import android.view.MotionEvent; import android.view.ViewGroup; import android.view.Window; import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.Switch; +import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; @@ -22,12 +32,23 @@ import net.kdt.pojavlaunch.extra.ExtraConstants; import net.kdt.pojavlaunch.extra.ExtraCore; import net.kdt.pojavlaunch.extra.ExtraListener; import net.kdt.pojavlaunch.prefs.screens.LauncherPreferenceFragment; +import net.kdt.pojavlaunch.tasks.AsyncAssetManager; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; public class MyDialogFragment extends DialogFragment { private static final int FILE_SELECT_CODE_JSON = 0; private static final int FILE_SELECT_CODE_ZIP = 1; + private static LinearLayout pluginList; + private static File disabledPluginsDirectory; + private static File pluginsDirectory; + + @SuppressLint("ClickableViewAccessibility") @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { @@ -40,6 +61,8 @@ public class MyDialogFragment extends DialogFragment { final Button loadConfig = dialog.findViewById(R.id.loadConfig); final Button loadPlugin = dialog.findViewById(R.id.loadPlugin); + pluginList = dialog.findViewById(R.id.pluginsList); + addPluginsToList(); loadConfig.setOnTouchListener((v, event) -> { if (event.getAction() == MotionEvent.ACTION_DOWN) { @@ -83,6 +106,144 @@ public class MyDialogFragment extends DialogFragment { return false; }; + private void addPluginsToList() { + // Path for plugins and disabled plugins + pluginsDirectory = new File(Tools.DIR_DATA + "/plugins/"); + disabledPluginsDirectory = new File(Tools.DIR_DATA + "/disabledPlugins/"); + + // Check if disabledPluginsDirectory exists, if not, create it. + if (!disabledPluginsDirectory.exists()) { + boolean success = disabledPluginsDirectory.mkdirs(); + if (!success) { + Log.e("TAG", "Failed to create directory: " + disabledPluginsDirectory.getPath()); + // If we failed to create the directory, we can return early from this method + return; + } + } + + // Clear the existing list + pluginList.removeAllViews(); + + // Process the enabled plugins + processPluginDirectory(pluginsDirectory, true); + + // Process the disabled plugins + processPluginDirectory(disabledPluginsDirectory, false); + } + + private void processPluginDirectory(File directory, boolean enabled) { + File[] files = directory.listFiles(); + + if (files != null) { // Make sure the directory isn't empty + for (File file : files) { + if (file.isDirectory()) { // This line weeds out other directories/folders + // Create a new LinearLayout + LinearLayout newLinearLayout = new LinearLayout(getContext()); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + layoutParams.setMargins(0, 10, 0, 10); // Top margin is 10dp + newLinearLayout.setLayoutParams(layoutParams); + newLinearLayout.setPadding(10, 10, 10, 10); // Padding is 10dp + newLinearLayout.setOrientation(LinearLayout.HORIZONTAL); + + // Create a new TextView + TextView textView = new TextView(getContext()); + LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); + textParams.setMargins(30, 0, 0, 0); // Left margin is 30dp + textView.setLayoutParams(textParams); + textView.setText(file.getName()); + textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16); // Text size is 16sp + + // Create a new Switch + Switch pluginSwitch = new Switch(getContext()); + pluginSwitch.setChecked(enabled); // Set the initial state based on the directory + + // Set an onCheckedChangeListener on the Switch + pluginSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + File fromDir = isChecked ? disabledPluginsDirectory : pluginsDirectory; + File toDir = isChecked ? pluginsDirectory : disabledPluginsDirectory; + + File fromFile = new File(fromDir, file.getName()); + File toFile = new File(toDir, file.getName()); + + // Move the directory + boolean success = fromFile.renameTo(toFile); + + if (!success) { + // Handle failure + Log.e("TAG", "Failed to move directory: " + fromFile.getPath() + " to " + toFile.getPath()); + } + }); + + // Add the TextView and Switch to the LinearLayout + newLinearLayout.addView(textView); + newLinearLayout.addView(pluginSwitch); + + // Add the LinearLayout to the parent layout + pluginList.addView(newLinearLayout); + } + } + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == FILE_SELECT_CODE_JSON) { + if (resultCode == RESULT_OK) { + Uri uri = data.getData(); + File config = new File(Tools.DIR_DATA, "config.json"); // file to overwrite + try { + Log.d("TAG", "Starting copy: " + uri.getPath()); + InputStream inputStream = getContext().getContentResolver().openInputStream(uri); + FileOutputStream fileOutputStream = new FileOutputStream(config); + byte buf[] = new byte[1024]; + int len; + while ((len = inputStream.read(buf)) > 0) { + fileOutputStream.write(buf, 0, len); + } + Toast.makeText(getContext(), "Config loaded. Please restart the app.", + Toast.LENGTH_SHORT).show(); + + fileOutputStream.close(); + inputStream.close(); + } catch (IOException e1) { + Log.d("error", "Error with file " + e1); + } + } + } else if(requestCode == FILE_SELECT_CODE_ZIP) { + Uri uri = data.getData(); + // Create a temporary file in your app's cache directory + File tempFile = new File(getContext().getCacheDir(), "temp.zip"); + + try { + // Open an InputStream to the selected file + InputStream inputStream = getContext().getContentResolver().openInputStream(uri); + + // Open a FileOutputStream to your temporary file + FileOutputStream fileOutputStream = new FileOutputStream(tempFile); + + // Copy the contents + byte[] buffer = new byte[1024]; + int read; + while ((read = inputStream.read(buffer)) != -1) { + fileOutputStream.write(buffer, 0, read); + } + + // Close the streams + fileOutputStream.close(); + inputStream.close(); + + // Now you can pass the File object to your method + AsyncAssetManager.extractPluginZip(tempFile); + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + super.onActivityResult(requestCode, resultCode, data); + } + private void showFileChooser(int requestCode) { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); @@ -92,7 +253,9 @@ public class MyDialogFragment extends DialogFragment { intent.addCategory(Intent.CATEGORY_OPENABLE); break; case FILE_SELECT_CODE_ZIP: - intent.setType("application/zip"); + intent.setType("*/*"); + String[] mimetypes = {"application/zip", "application/x-zip-compressed", "multipart/x-zip"}; + intent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes); intent.addCategory(Intent.CATEGORY_OPENABLE); break; default: @@ -100,8 +263,6 @@ public class MyDialogFragment extends DialogFragment { intent.addCategory(Intent.CATEGORY_OPENABLE); } - - try { startActivityForResult( Intent.createChooser(intent, "Select a File to Upload"), diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/AsyncAssetManager.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/AsyncAssetManager.java index 86dbe41c7..076f5a843 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/AsyncAssetManager.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/AsyncAssetManager.java @@ -22,6 +22,8 @@ import java.io.InputStream; public class AsyncAssetManager { + private static final String PLUGIN_PATH = "plugins"; + private AsyncAssetManager(){} /** @@ -86,8 +88,8 @@ public class AsyncAssetManager { unpackComponent(ctx, "security", true); unpackComponent(ctx, "arc_dns_injector", true); unpackComponent(ctx, "forge_installer", true); - Tools.copyAssetFile(ctx,"rt4.jar",Tools.DIR_DATA, true); - Tools.copyAssetFile(ctx,"config.json",Tools.DIR_DATA, true); + Tools.copyAssetFile(ctx,"rt4.jar",Tools.DIR_DATA, true); // Change this to true for debugging + Tools.copyAssetFile(ctx,"config.json",Tools.DIR_DATA, false); // Unzip the plugins for use. extractAllPlugins(ctx); // Can comment this out to keep the plugins saved, rewrites them ever time it launches... @@ -99,14 +101,36 @@ public class AsyncAssetManager { }); } - private static void extractAllPlugins(Context ctx) throws IOException { - String pluginsPath = "plugins"; // The folder where your plugins reside in the assets - AssetManager am = ctx.getAssets(); - String[] plugins = am.list(pluginsPath); - if(plugins != null) { - for(String plugin : plugins) { - Tools.copyAssetFile(ctx, pluginsPath + "/" + plugin, Tools.DIR_DATA, true); + // Path for plugins and disabled plugins + File pluginsDirectory = new File(Tools.DIR_DATA + "/plugins/"); + File disabledPluginsDirectory = new File(Tools.DIR_DATA + "/disabledPlugins/"); + + // Check if disabledPluginsDirectory exists, if not, create it. + if (!disabledPluginsDirectory.exists()) { + boolean success = disabledPluginsDirectory.mkdirs(); + if (!success) { + Log.e("TAG", "Failed to create directory: " + disabledPluginsDirectory.getPath()); + // If we failed to create the directory, we can return early from this method + return; + } + } + + String[] plugins = ctx.getAssets().list(PLUGIN_PATH); + if (plugins != null) { + for (String plugin : plugins) { + // Name of the directory that would be created when the plugin is extracted + String pluginDirectoryName = plugin.substring(0, plugin.lastIndexOf('.')); + File installedPluginDirectory = new File(pluginsDirectory, pluginDirectoryName); + File disabledPluginDirectory = new File(disabledPluginsDirectory, pluginDirectoryName); + + // If a directory with this name already exists in either the plugins directory or the disabled plugins directory, skip this plugin + if (installedPluginDirectory.exists() || disabledPluginDirectory.exists()) { + continue; + } + + // Extract the plugin + Tools.copyAssetFile(ctx, PLUGIN_PATH + "/" + plugin, Tools.DIR_DATA, true); Tools.ZipTool.unzip( new File(Tools.DIR_DATA + "/" + plugin), new File(Tools.DIR_DATA + "/plugins/") @@ -115,6 +139,11 @@ public class AsyncAssetManager { } } + + public static void extractPluginZip(File plugin) throws IOException { + Tools.ZipTool.unzip(plugin, new File(Tools.DIR_DATA + "/plugins/")); + } + private static void unpackComponent(Context ctx, String component, boolean privateDirectory) throws IOException { AssetManager am = ctx.getAssets(); String rootDir = privateDirectory ? Tools.DIR_DATA : Tools.DIR_GAME_HOME; diff --git a/app_pojavlauncher/src/main/res/drawable/dialoguebkg.xml b/app_pojavlauncher/src/main/res/drawable/dialoguebkg.xml index e854de458..46bc4060d 100644 --- a/app_pojavlauncher/src/main/res/drawable/dialoguebkg.xml +++ b/app_pojavlauncher/src/main/res/drawable/dialoguebkg.xml @@ -2,7 +2,7 @@ + android:color="#232323"/>