From 17c435da39eca800f3d72f582068273573b5b3e8 Mon Sep 17 00:00:00 2001 From: alexytomi <60690056+alexytomi@users.noreply.github.com> Date: Thu, 19 Jun 2025 18:49:57 +0800 Subject: [PATCH 1/5] qol[Demo]: Turn demo mode error into box TODO: actually make these translatable --- .../net/kdt/pojavlaunch/LauncherActivity.java | 4 ++- .../net/kdt/pojavlaunch/PojavProfile.java | 26 +++++++++++++++ .../main/java/net/kdt/pojavlaunch/Tools.java | 27 +++++++++++++++ .../fragments/LocalLoginFragment.java | 6 ++++ .../fragments/MainMenuFragment.java | 33 +++++++++---------- .../fragments/ProfileTypeSelectFragment.java | 7 ++-- 6 files changed, 82 insertions(+), 21 deletions(-) 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 9b8834d17..26d01c6c4 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java @@ -1,6 +1,8 @@ package net.kdt.pojavlaunch; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; +import static net.kdt.pojavlaunch.Tools.hasNoOnlineProfileDialog; + import android.Manifest; import android.app.NotificationManager; import android.content.Context; @@ -139,7 +141,7 @@ public class LauncherActivity extends BaseActivity { } if (isOlderThan13) { - Toast.makeText(this, R.string.toast_not_available_demo, Toast.LENGTH_LONG).show(); + hasNoOnlineProfileDialog(this, getString(R.string.global_error), "This version is not available in demo mode."); return false; } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java index ae9d5421e..efd57bb8d 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java @@ -8,6 +8,13 @@ import androidx.annotation.Nullable; import net.kdt.pojavlaunch.value.MinecraftAccount; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + public class PojavProfile { private static final String PROFILE_PREF = "pojav_profile"; private static final String PROFILE_PREF_FILE = "file"; @@ -29,6 +36,25 @@ public class PojavProfile { } return name; } + + public static List getAllProfiles(){ + List mcAccountList = new ArrayList<>();; + for (String accountName : getAllProfilesList()){ + mcAccountList.add(MinecraftAccount.load(accountName)); + } + return mcAccountList; + } + + public static List getAllProfilesList(){ + List accountList = new ArrayList<>(); + File accountFolder = new File(Tools.DIR_ACCOUNT_NEW); + if(accountFolder.exists() && accountFolder.list() != null){ + for (String fileName : Objects.requireNonNull(accountFolder.list())) { + accountList.add(fileName.substring(0, fileName.length() - 5)); + } + } + return accountList; + } public static void setCurrentProfile(@NonNull Context ctx, @Nullable Object obj) { SharedPreferences.Editor pref = getPrefs(ctx).edit(); 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 8ed093b26..c50f89a9c 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -3,6 +3,7 @@ package net.kdt.pojavlaunch; import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION_CODES.P; import static net.kdt.pojavlaunch.PojavApplication.sExecutorService; +import static net.kdt.pojavlaunch.PojavProfile.getAllProfiles; import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_IGNORE_NOTCH; import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_NOTCH_SIZE; @@ -1452,4 +1453,30 @@ public final class Tools { MinecraftAccount currentProfile = PojavProfile.getCurrentProfileContent(ctx, null); return currentProfile == null || currentProfile.isLocal(); } + public static boolean hasOnlineProfile(){ + for (MinecraftAccount accountToCheck : getAllProfiles()) { + if (!accountToCheck.isLocal() || !accountToCheck.isDemo()) { + return true; + } + } + return false; + } + public static void hasNoOnlineProfileDialog(Activity activity){ + if (hasOnlineProfile()){ + } else dialogOnUiThread(activity, "No Minecraft Account Found", "Please log into your Minecraft: Java Edition account to use this feature."); + } + public static void hasNoOnlineProfileDialog(Activity activity, String customTitle, String customMessage){ + if (hasOnlineProfile()){ + } else dialogOnUiThread(activity, customTitle, customMessage); + } + public static void hasNoOnlineProfileDialog(Activity activity, Runnable run){ + if (hasOnlineProfile()){ + run.run(); + } else dialogOnUiThread(activity, "No Minecraft Account Found", "Please log into your Minecraft: Java Edition account to use this feature."); + } + public static void hasNoOnlineProfileDialog(Activity activity, Runnable run, String customTitle, String customMessage){ + if (hasOnlineProfile()){ + run.run(); + } else dialogOnUiThread(activity, customTitle, customMessage); + } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LocalLoginFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LocalLoginFragment.java index 86a00e375..e4e2e5d4f 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LocalLoginFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LocalLoginFragment.java @@ -1,5 +1,7 @@ package net.kdt.pojavlaunch.fragments; +import static net.kdt.pojavlaunch.Tools.hasOnlineProfile; + import android.content.Context; import android.os.Bundle; import android.view.View; @@ -31,6 +33,10 @@ public class LocalLoginFragment extends Fragment { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + // This is overkill but meh + if (!hasOnlineProfile()){ + Tools.swapFragment(requireActivity(), MainMenuFragment.class, MainMenuFragment.TAG, null); + } mUsernameEditText = view.findViewById(R.id.login_edit_email); view.findViewById(R.id.login_button).setOnClickListener(v -> { if(!checkEditText()) { 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 364c3d0b1..a029d82c3 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 @@ -1,5 +1,7 @@ package net.kdt.pojavlaunch.fragments; +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.shareLog; @@ -53,11 +55,13 @@ public class MainMenuFragment extends Fragment { mNewsButton.setOnClickListener(v -> Tools.openURL(requireActivity(), Tools.URL_HOME)); mDiscordButton.setOnClickListener(v -> Tools.openURL(requireActivity(), getString(R.string.discord_invite))); mCustomControlButton.setOnClickListener(v -> startActivity(new Intent(requireContext(), CustomControlsActivity.class))); - mInstallJarButton.setOnClickListener(v -> runInstallerWithConfirmation(false)); - mInstallJarButton.setOnLongClickListener(v->{ - runInstallerWithConfirmation(true); - return true; - }); + if (hasOnlineProfile()) { + mInstallJarButton.setOnClickListener(v -> runInstallerWithConfirmation(false)); + mInstallJarButton.setOnLongClickListener(v -> { + runInstallerWithConfirmation(true); + return true; + }); + } else mInstallJarButton.setOnClickListener(v -> hasNoOnlineProfileDialog(requireActivity())); mEditProfileButton.setOnClickListener(v -> mVersionSpinner.openProfileEditor(requireActivity())); mPlayButton.setOnClickListener(v -> ExtraCore.setValue(ExtraConstants.LAUNCH_GAME, true)); @@ -65,13 +69,12 @@ public class MainMenuFragment extends Fragment { mShareLogsButton.setOnClickListener((v) -> shareLog(requireContext())); mOpenDirectoryButton.setOnClickListener((v)-> { - Tools.switchDemo(Tools.isDemoProfile(v.getContext())); // avoid switching accounts being able to access - if(Tools.isDemoProfile(v.getContext())){ - Toast.makeText(v.getContext(), R.string.toast_not_available_demo, Toast.LENGTH_LONG).show(); - return; - } - - openPath(v.getContext(), getCurrentProfileDirectory(), false); + if (hasOnlineProfile()) { + if (Tools.isDemoProfile(v.getContext())){ + hasNoOnlineProfileDialog(getActivity(), "Demo Profile not supported", "Please change accounts to use this function"); + } + openPath(v.getContext(), getCurrentProfileDirectory(), false); + } else hasNoOnlineProfileDialog(requireActivity()); }); @@ -97,12 +100,6 @@ public class MainMenuFragment extends Fragment { } private void runInstallerWithConfirmation(boolean isCustomArgs) { - // avoid using custom installers to install a version - if(Tools.isLocalProfile(requireContext()) || Tools.isDemoProfile(requireContext())){ - Toast.makeText(requireContext(), R.string.toast_not_available_demo, Toast.LENGTH_LONG).show(); - return; - } - if (ProgressKeeper.getTaskCount() == 0) Tools.installMod(requireActivity(), isCustomArgs); else diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileTypeSelectFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileTypeSelectFragment.java index bd8575069..9a82ccb9f 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileTypeSelectFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileTypeSelectFragment.java @@ -1,5 +1,8 @@ package net.kdt.pojavlaunch.fragments; +import static net.kdt.pojavlaunch.Tools.hasNoOnlineProfileDialog; +import static net.kdt.pojavlaunch.Tools.hasOnlineProfile; + import android.os.Bundle; import android.view.View; import android.widget.Toast; @@ -42,8 +45,8 @@ public class ProfileTypeSelectFragment extends Fragment { } private void tryInstall(Class fragmentClass, String tag){ - if(Tools.isLocalProfile(requireContext()) || Tools.isDemoProfile(requireContext())){ - Toast.makeText(requireContext(), R.string.toast_not_available_demo, Toast.LENGTH_LONG).show(); + if(!hasOnlineProfile()){ + hasNoOnlineProfileDialog(requireActivity()); } else { Tools.swapFragment(requireActivity(), fragmentClass, tag, null); } From 1e652fc3bc2ebb1d15c1f410f671ed46d7ff7be2 Mon Sep 17 00:00:00 2001 From: alexytomi <60690056+alexytomi@users.noreply.github.com> Date: Thu, 19 Jun 2025 18:50:31 +0800 Subject: [PATCH 2/5] fix[Login]: Prevent creation of local accounts when no Minecraft Account is detected --- .../net/kdt/pojavlaunch/fragments/SelectAuthFragment.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/SelectAuthFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/SelectAuthFragment.java index 781408988..516620698 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/SelectAuthFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/SelectAuthFragment.java @@ -1,5 +1,7 @@ package net.kdt.pojavlaunch.fragments; +import static net.kdt.pojavlaunch.Tools.hasNoOnlineProfileDialog; + import android.os.Bundle; import android.view.View; import android.widget.Button; @@ -24,6 +26,6 @@ public class SelectAuthFragment extends Fragment { Button mLocalButton = view.findViewById(R.id.button_local_authentication); mMicrosoftButton.setOnClickListener(v -> Tools.swapFragment(requireActivity(), MicrosoftLoginFragment.class, MicrosoftLoginFragment.TAG, null)); - mLocalButton.setOnClickListener(v -> Tools.swapFragment(requireActivity(), LocalLoginFragment.class, LocalLoginFragment.TAG, null)); + mLocalButton.setOnClickListener(v -> hasNoOnlineProfileDialog(requireActivity(), () -> Tools.swapFragment(requireActivity(), LocalLoginFragment.class, LocalLoginFragment.TAG, null))); } } From dae621043ceb6143e90448d83349212cd46e9d85 Mon Sep 17 00:00:00 2001 From: alexytomi <60690056+alexytomi@users.noreply.github.com> Date: Fri, 20 Jun 2025 23:35:27 +0800 Subject: [PATCH 3/5] fix[Tools/hasOnlineProfile]: Faulty logic fix --- app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c50f89a9c..8ae348bce 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -1455,7 +1455,7 @@ public final class Tools { } public static boolean hasOnlineProfile(){ for (MinecraftAccount accountToCheck : getAllProfiles()) { - if (!accountToCheck.isLocal() || !accountToCheck.isDemo()) { + if (!accountToCheck.isLocal() && !accountToCheck.isDemo()) { return true; } } From 9e877dfb12a27351b6062af8bf9cc2078b4939ac Mon Sep 17 00:00:00 2001 From: alexytomi <60690056+alexytomi@users.noreply.github.com> Date: Sat, 21 Jun 2025 00:00:41 +0800 Subject: [PATCH 4/5] fix[i18n]: Add localization --- .../java/net/kdt/pojavlaunch/LauncherActivity.java | 2 +- .../src/main/java/net/kdt/pojavlaunch/Tools.java | 4 ++-- .../kdt/pojavlaunch/fragments/MainMenuFragment.java | 12 ++++++------ app_pojavlauncher/src/main/res/values/strings.xml | 5 +++++ 4 files changed, 14 insertions(+), 9 deletions(-) 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 26d01c6c4..a3c296523 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java @@ -141,7 +141,7 @@ public class LauncherActivity extends BaseActivity { } if (isOlderThan13) { - hasNoOnlineProfileDialog(this, getString(R.string.global_error), "This version is not available in demo mode."); + hasNoOnlineProfileDialog(this, getString(R.string.global_error), getString(R.string.demo_versions_supported)); return false; } } 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 8ae348bce..24acb1ef1 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -1463,7 +1463,7 @@ public final class Tools { } public static void hasNoOnlineProfileDialog(Activity activity){ if (hasOnlineProfile()){ - } else dialogOnUiThread(activity, "No Minecraft Account Found", "Please log into your Minecraft: Java Edition account to use this feature."); + } else dialogOnUiThread(activity, activity.getString(R.string.no_minecraft_account_found), activity.getString(R.string.feature_requires_java_account)); } public static void hasNoOnlineProfileDialog(Activity activity, String customTitle, String customMessage){ if (hasOnlineProfile()){ @@ -1472,7 +1472,7 @@ public final class Tools { public static void hasNoOnlineProfileDialog(Activity activity, Runnable run){ if (hasOnlineProfile()){ run.run(); - } else dialogOnUiThread(activity, "No Minecraft Account Found", "Please log into your Minecraft: Java Edition account to use this feature."); + } else dialogOnUiThread(activity, activity.getString(R.string.no_minecraft_account_found), activity.getString(R.string.feature_requires_java_account)); } public static void hasNoOnlineProfileDialog(Activity activity, Runnable run, String customTitle, String customMessage){ if (hasOnlineProfile()){ 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 a029d82c3..ee59d87e4 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 @@ -69,12 +69,12 @@ public class MainMenuFragment extends Fragment { mShareLogsButton.setOnClickListener((v) -> shareLog(requireContext())); mOpenDirectoryButton.setOnClickListener((v)-> { - if (hasOnlineProfile()) { - if (Tools.isDemoProfile(v.getContext())){ - hasNoOnlineProfileDialog(getActivity(), "Demo Profile not supported", "Please change accounts to use this function"); - } - openPath(v.getContext(), getCurrentProfileDirectory(), false); - } else hasNoOnlineProfileDialog(requireActivity()); + if (Tools.isDemoProfile(v.getContext())){ // Say a different message when on demo profile since they might see the hidden demo folder + hasNoOnlineProfileDialog(getActivity(), getString(R.string.demo_unsupported), getString(R.string.change_account)); + } else if (!hasOnlineProfile()) { // Otherwise display the generic pop-up to log in + hasNoOnlineProfileDialog(requireActivity()); + } else openPath(v.getContext(), getCurrentProfileDirectory(), false); + }); diff --git a/app_pojavlauncher/src/main/res/values/strings.xml b/app_pojavlauncher/src/main/res/values/strings.xml index 369ee49aa..8e2fe4f52 100644 --- a/app_pojavlauncher/src/main/res/values/strings.xml +++ b/app_pojavlauncher/src/main/res/values/strings.xml @@ -445,4 +445,9 @@ May help with shaderpack glitches. Disable if not needed, can cause crashes. Error Filtering Amethyst + Only Vanilla 1.3.1 and above are supported on demo accounts + Demo Profile not supported + Please change accounts to use this function + No Minecraft Account Found + This feature requires a Microsoft account that owns Minecraft Java Edition. From dcdcdff363090ecb2169425269447977cedd2fc3 Mon Sep 17 00:00:00 2001 From: alexytomi <60690056+alexytomi@users.noreply.github.com> Date: Sat, 21 Jun 2025 12:48:03 +0800 Subject: [PATCH 5/5] refactor[Tools]: Refactor better demo/local dialog Should also fix demo message being missing in some cases (particularly in the open directory button when both a demo and ms acc is logged on) --- .../main/java/net/kdt/pojavlaunch/Tools.java | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 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 24acb1ef1..a5f876aff 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -1461,22 +1461,29 @@ public final class Tools { } return false; } - public static void hasNoOnlineProfileDialog(Activity activity){ - if (hasOnlineProfile()){ - } else dialogOnUiThread(activity, activity.getString(R.string.no_minecraft_account_found), activity.getString(R.string.feature_requires_java_account)); + + public static void hasNoOnlineProfileDialog(Activity activity, @Nullable Runnable run, @Nullable String customTitle, @Nullable String customMessage){ + if (hasOnlineProfile() && !Tools.isDemoProfile(activity)){ + if (run != null) { // Demo profile handling should be using customTitle and customMessage + run.run(); + } + } else { // If there is no online profile, show a dialog + customTitle = customTitle == null ? activity.getString(R.string.no_minecraft_account_found) : customTitle; + customMessage = customMessage == null ? activity.getString(R.string.feature_requires_java_account) : customMessage; + dialogOnUiThread(activity, customTitle, customMessage); + } } - public static void hasNoOnlineProfileDialog(Activity activity, String customTitle, String customMessage){ - if (hasOnlineProfile()){ - } else dialogOnUiThread(activity, customTitle, customMessage); + + // Some boilerplate to reduce boilerplate elsewhere + public static void hasNoOnlineProfileDialog(Activity activity){ + hasNoOnlineProfileDialog(activity, null, null, null); } public static void hasNoOnlineProfileDialog(Activity activity, Runnable run){ - if (hasOnlineProfile()){ - run.run(); - } else dialogOnUiThread(activity, activity.getString(R.string.no_minecraft_account_found), activity.getString(R.string.feature_requires_java_account)); + hasNoOnlineProfileDialog(activity, run, null, null); } - public static void hasNoOnlineProfileDialog(Activity activity, Runnable run, String customTitle, String customMessage){ - if (hasOnlineProfile()){ - run.run(); - } else dialogOnUiThread(activity, customTitle, customMessage); + public static void hasNoOnlineProfileDialog(Activity activity, String customTitle, String customMessage){ + hasNoOnlineProfileDialog(activity, null, customTitle, customMessage); } + + }