From e2efd00ffb69025a43643ccb724a387eeef6f6dc Mon Sep 17 00:00:00 2001 From: alexytomi <60690056+alexytomi@users.noreply.github.com> Date: Sun, 28 Dec 2025 14:42:10 +0800 Subject: [PATCH] add: Delete Sodium and dependents button in Sodium warning --- .../main/java/net/kdt/pojavlaunch/Tools.java | 73 +++++++++++++++---- .../fragments/MainMenuFragment.java | 22 +++--- 2 files changed, 69 insertions(+), 26 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java index 38334f6c1..d6256b4cd 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -28,7 +28,6 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; -import android.os.FileObserver; import android.os.Handler; import android.os.Looper; import android.provider.DocumentsContract; @@ -213,24 +212,66 @@ public final class Tools { } /** - * Optimization mods based on Sodium can mitigate the render distance issue. Check if Sodium - * or its derivative is currently installed to skip the render distance check. - * @param gameDir current game directory - * @return whether sodium or a sodium-based mod is installed + * @return The selected "Custom path" of the current profile */ - public static boolean hasSodium(File gameDir) { + @NonNull + private static File getGameDir() { + return getGameDirPath(LauncherProfiles.getCurrentProfile()); + } + + /** + * Searches for mod in mods directory of current selected profile + * @param filenames Filename(s) of the .jar mod(s) + * @return Whether or not the .jar is found + */ + public static boolean hasMods(String... filenames) { + File gameDir = getGameDir(); File modsDir = new File(gameDir, "mods"); - File[] mods = modsDir.listFiles(file -> file.isFile() && file.getName().endsWith(".jar")); - if(mods == null) return false; - for(File file : mods) { - String name = file.getName(); - if(name.contains("sodium") || - name.contains("embeddium") || - name.contains("rubidium")) return true; + File[] modFiles = modsDir.listFiles(file -> file.isFile() && file.getName().endsWith(".jar")); + if (modFiles == null) return false; + for (File file : modFiles) { + for (String filename : filenames) + if (file.getName().contains(filename)) return true; } return false; } + /** + * Tries to delete any sodium related mods of the currently selected profile via string matching + * the files in the mods folder. + */ + public static void deleteSodiumMods() { + File modsDir = new File(getGameDir(), "mods"); + File[] mods = modsDir.listFiles(file -> file.isFile() && file.getName().endsWith(".jar")); + if(mods == null) ; + for(File file : mods) { + String name = file.getName().toLowerCase(); + if(name.contains("sodium") || + name.contains("beddium") || // Also covers embeddium + name.contains("rubidium") || + name.contains("xenon") || // Name conflicts with another mod + name.contains("celeritas") || + name.contains("relictium") || + name.contains("vintagium") || + name.contains("podium") || + name.contains("indium") || + name.contains("lazurite") || + name.contains("iris") || + name.contains("monocle") || + name.contains("voxy") || + name.contains("nvidium") || + name.contains("chloride") || + name.contains("bedrodium") || + name.contains("substrate") || // Name conflicts with another mod + name.contains("blendium") || + name.contains("ryoamium") + // The name conflicts are for pretty dead mods so we ignore them. + // I doubt they're using some mod with less than 5k downloads with sodium. + ) if(!file.delete()) + throw new RuntimeException("Failed to delete Sodium and related mods!"); + } + } + /** * Search for TouchController mod to automatically enable TouchController mod support. * @@ -268,10 +309,10 @@ public final class Tools { return info.isAdreno() && info.glesMajorVersion >= 3; } - private static boolean checkRenderDistance(File gamedir) { + private static boolean affectedByLTWRenderDistanceIssue() { if(!"opengles3_ltw".equals(Tools.LOCAL_RENDERER)) return false; if(!affectedByRenderDistanceIssue()) return false; - if(hasSodium(gamedir)) return false; + if(hasMods("sodium", "embeddium", "rubidium")) return false; int renderDistance; try { @@ -316,7 +357,7 @@ public final class Tools { File gamedir = Tools.getGameDirPath(minecraftProfile); startControllableMitigation(activity, gamedir); startOldLegacy4JMitigation(activity, gamedir); - if(checkRenderDistance(gamedir)) { + if(affectedByLTWRenderDistanceIssue()) { LifecycleAwareAlertDialog.DialogCreator dialogCreator = ((alertDialog, dialogBuilder) -> dialogBuilder.setMessage(activity.getString(R.string.ltw_render_distance_warning_msg)) .setPositiveButton(android.R.string.ok, (d, w)->{})); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/MainMenuFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/MainMenuFragment.java index 07e24ddd8..3c55940a4 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/MainMenuFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/MainMenuFragment.java @@ -4,13 +4,12 @@ import static net.kdt.pojavlaunch.Tools.dialogOnUiThread; import static net.kdt.pojavlaunch.Tools.hasNoOnlineProfileDialog; import static net.kdt.pojavlaunch.Tools.hasOnlineProfile; import static net.kdt.pojavlaunch.Tools.openPath; +import static net.kdt.pojavlaunch.Tools.runOnUiThread; import static net.kdt.pojavlaunch.Tools.shareLog; -import android.content.DialogInterface; +import android.app.Dialog; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Bundle; -import android.os.CountDownTimer; import android.view.View; import android.widget.Button; import android.widget.ImageButton; @@ -24,14 +23,12 @@ import androidx.fragment.app.Fragment; import com.kdt.mcgui.mcVersionSpinner; import net.kdt.pojavlaunch.CustomControlsActivity; -import net.kdt.pojavlaunch.PojavProfile; import net.kdt.pojavlaunch.R; import net.kdt.pojavlaunch.Tools; import net.kdt.pojavlaunch.extra.ExtraConstants; import net.kdt.pojavlaunch.extra.ExtraCore; import net.kdt.pojavlaunch.prefs.LauncherPreferences; import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper; -import net.kdt.pojavlaunch.value.MinecraftAccount; import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles; import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile; @@ -72,11 +69,16 @@ public class MainMenuFragment extends Fragment { mEditProfileButton.setOnClickListener(v -> mVersionSpinner.openProfileEditor(requireActivity())); mPlayButton.setOnClickListener(v -> { - MinecraftProfile minecraftProfile = LauncherProfiles.getCurrentProfile(); - File gameDir = Tools.getGameDirPath(minecraftProfile); - if (Tools.hasSodium(gameDir) && !(LauncherPreferences.DEFAULT_PREF.getBoolean("sodium_override", false))) { - Tools.dialogOnUiThread(requireActivity(), - R.string.sodium_warning_title, R.string.sodium_warning_message); + if (Tools.hasMods("sodium") && !(LauncherPreferences.DEFAULT_PREF.getBoolean("sodium_override", false))) { + AlertDialog sodiumWarningDialog = new AlertDialog.Builder(requireContext()) + .setTitle(R.string.sodium_warning_title) + .setMessage(R.string.sodium_warning_message) + .setNeutralButton(R.string.delete_sodium, (d,w)-> { + Tools.deleteSodiumMods(); + ExtraCore.setValue(ExtraConstants.LAUNCH_GAME, true); + }) + .create(); + sodiumWarningDialog.show(); } else ExtraCore.setValue(ExtraConstants.LAUNCH_GAME, true);