diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 89b88c5629..76aa875586 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -17,7 +17,7 @@ body: attributes: label: The log file and images/videos description: | - The log file called `latestlog.txt` is located under `/storage/emulated/0/Android/data/org.angelauramc.amethyst/files` (on Android 10 and higher) or `/storage/emulated/0/games/Amethyst/` (on Android 9 and lower). You may have to activate an option in your file explorer to see hidden files and folders. Recommended file managers are ZArchiver and MiXplorer. | + The log file called `latestlog.txt` is located under `/storage/emulated/0/Android/data/org.angelauramc.amethyst/files` (on Android 10 and higher) or `/storage/emulated/0/games/Copper/` (on Android 9 and lower). You may have to activate an option in your file explorer to see hidden files and folders. Recommended file managers are ZArchiver and MiXplorer. | You can also upload here screenshots or videos of the buggy behavior, if possible. Tip: You can attach files by clicking this area to highlight it and then dragging files in or select them on 🖼 option at the toolbar. Do not click anything before the file successfully uploads, otherwise the upload is going to stop and the file won't attach. @@ -29,7 +29,7 @@ body: label: Steps To Reproduce description: Steps to reproduce the issue. placeholder: | - 1. Start Amethyst + 1. Start Copper ... *(your set of actions to reproduce the bug)* render: markdown validations: @@ -51,12 +51,12 @@ body: - **Device model**: Huawei P30 Pro 8/512G - **CPU architecture**: arm64 (can be arm64, arm, x86_64 or x86 depending on the device) - **Android version**: 10 - - **Amethyst version**: (can be found in Android Apps settings, for example `dahlia-20230813-5e8842b-v3_openjdk`) + - **Copper version**: (can be found in Android Apps settings, for example `dahlia-20230813-5e8842b-v3_openjdk`) value: | - Device model: - CPU architecture: - Android version: - - Amethyst version: + - Copper version: render: markdown validations: required: true diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 4e4ecffc06..b973d4f181 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -28,46 +28,23 @@ jobs: distribution: 'temurin' java-version: '21' - - name: Get JRE 8 - uses: dawidd6/action-download-artifact@v9 + - name: Get LTW + run: | + sudo apt update && sudo apt install -y wget + mkdir -p app_pojavlauncher/libs + cd app_pojavlauncher/libs + wget https://github.com/CopperLauncher/LTW/releases/latest/download/ltw-release.aar + + - name: Get JRE8 + uses: dawidd6/action-download-artifact@v6 with: workflow: build.yml path: app_pojavlauncher/src/main/assets/components/jre - workflow_conclusion: completed + workflow_conclusion: success repo: AngelAuraMC/angelauramc-openjdk-build branch: buildjre8 name: jre8-pojav - # - name: Get JRE17 - # uses: dawidd6/action-download-artifact@v9 - # with: - # workflow: build.yml - # path: app_pojavlauncher/src/main/assets/components/jre-new - # workflow_conclusion: completed - # repo: AngelAuraMC/angelauramc-openjdk-build - # branch: buildjre17-21 - # name: jre17-pojav - # - # - name: Get JRE21 - # uses: dawidd6/action-download-artifact@v9 - # with: - # workflow: build.yml - # path: app_pojavlauncher/src/main/assets/components/jre-21 - # workflow_conclusion: completed - # repo: AngelAuraMC/angelauramc-openjdk-build - # branch: buildjre17-21 - # name: jre21-pojav - # - # - name: Get JRE25 - # uses: dawidd6/action-download-artifact@v9 - # with: - # workflow: build.yml - # path: app_pojavlauncher/src/main/assets/components/jre-25 - # workflow_conclusion: completed - # repo: FCL-Team/Android-OpenJDK-Build - # branch: Build_JRE_25 - # name: jre25-multiarch - - uses: gradle/actions/setup-gradle@v4 with: validate-wrappers: false @@ -94,6 +71,15 @@ jobs: gradle :app_pojavlauncher:assembleDebug mv app_pojavlauncher/build/outputs/apk/debug/app_pojavlauncher-debug.apk out/app-debug.apk + - name: Build APK without runtime + run: | + rm -rf app_pojavlauncher/src/main/assets/components/jre + rm -rf app_pojavlauncher/src/main/assets/components/jre-new + rm -rf app_pojavlauncher/src/main/assets/components/jre-21 + rm -rf app_pojavlauncher/src/main/assets/components/jre-25 + ./gradlew assembleDebug + mv app_pojavlauncher/build/outputs/apk/debug/app_pojavlauncher-debug.apk out/app-debug-noruntime.apk + - name: Gen md5sums run: | md5sum out/app-debug.apk > out/app-debug.md5 @@ -104,6 +90,11 @@ jobs: name: app-debug (recommended) path: out/app-debug.* + - name: Upload APK (without runtime) + uses: actions/upload-artifact@v4 + with: + name: app-debug-noruntime + path: out/app-debug-noruntime.* - name: Upload release APK uses: actions/upload-artifact@v4 with: diff --git a/MobileGlues b/MobileGlues new file mode 160000 index 0000000000..694dfc2dc2 --- /dev/null +++ b/MobileGlues @@ -0,0 +1 @@ +Subproject commit 694dfc2dc21b02eca020473fbff4e589f3045e2a diff --git a/README.md b/README.md index ffe97159fe..6a9da53a15 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,27 @@ -

Angel Aura Amethyst

- -Amethyst logo - -[![Android CI](https://github.com/AngelAuraMC/Amethyst-Android/workflows/Android%20CI/badge.svg)](https://github.com/AngelAuraMC/Amethyst-Android/actions) -[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/AngelAuraMC/Amethyst-Android)](https://github.com/AngelAuraMC/Amethyst-Android/actions) -[![Crowdin](https://badges.crowdin.net/pojavlauncher/localized.svg)](https://crowdin.com/project/pojavlauncher) -[![Discord](https://img.shields.io/discord/724163890803638273.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/5ptqkyZxEy) - -*From [Boardwalk](https://github.com/zhuowei/Boardwalk)'s ashes and [PojavLauncher](https://github.com/PojavLauncherTeam/PojavLauncher)'s ruined reputation, here comes Amethyst!* - -Amethyst is a launcher that allows you to play Minecraft: Java Edition on your Android and [iOS](https://github.com/AngelAuraMC/Amethyst-iOS) devices. - -For more details, check out our [wiki](https://wiki.angelauramc.dev)! +

Copper Launcher

+ +Copper logo + +

+ GitHub commit activity + Platform + Min SDK + Android CI + Crowdin + Discord + GitHub + CurseForge + Modrinth User + Modrinth Org +

+

+ +Copper is a fork of [Amethyst](https://github.com/AngelAuraMC/Amethyst-Android) that allows you to play Minecraft: Java Edition on your Android devices. ## Table of Contents * [Introduction](#introduction) -* [Getting Amethyst](#getting-amethyst) +* [Getting Copper](#getting-copper) * [Building](#building) * [Quick Build (Recommended)](#quick-build-recommended) * [Detailed Build](#detailed-build) @@ -31,25 +36,26 @@ For more details, check out our [wiki](https://wiki.angelauramc.dev)! ## Introduction -* Amethyst is a Minecraft: Java Edition launcher for Android and iOS based on [Boardwalk](https://github.com/zhuowei/Boardwalk) and [PojavLauncher](https://github.com/PojavLauncherTeam/PojavLauncher) +* Copper is a Minecraft: Java Edition launcher for Android based on [Boardwalk](https://github.com/zhuowei/Boardwalk) and [PojavLauncher](https://github.com/PojavLauncherTeam/PojavLauncher) * This launcher can launch almost all available Minecraft versions ranging from rd-132211 to 1.21 snapshots (including Combat Test versions) * Modding via Forge and Fabric are also supported. -* This repository contains source code for Android. For iOS/iPadOS, check out [Amethyst-iOS](https://github.com/AngelAuraMC/Amethyst-iOS). +* This repository contains source code for Android. -## Getting Amethyst +## Getting Copper -You can get Amethyst via two methods: +You can get Copper via three methods: -1. **Releases:** Download the latest prebuilt app from [nightly.link](https://nightly.link/AngelAuraMC/Amethyst-Android/workflows/android/v3_openjdk/app-debug%20%28recommended%29.zip) or select an older version from our [automatic builds](https://github.com/AngelAuraMC/Amethyst-Android/actions). -2. **Build from Source:** Follow the [building instructions](#building) below. +1. **Nightly** Download the latest artifact from [Nightly.link](https://nightly.link/CopperLauncher/Copper-Android/workflows/android/v3_openjdk?preview) +2. **Releases:** Download the latest prebuilt app [from Releases](https://github.com/CopperLauncher/Copper-android/releases/) +3. **Build from Source:** Follow the [building instructions](#building) below. ## Building ### Quick Build (Recommended) -The easiest way to build Amethyst is to use the pre-built JREs provided by our CI. +The easiest way to build Copper is to use the pre-built JREs provided by our CI. -1. Clone the repository: `git clone --recursive https://github.com/AngelAuraMC/Amethyst-Android.git` +1. Clone the repository: `git clone --recursive https://github.com/CopperLauncher/CopperLauncher.git` 2. Build the launcher: `./gradlew :app_pojavlauncher:assembleDebug` (Use `gradlew.bat` on Windows) The built APK will be located in `app_pojavlauncher/build/outputs/apk/debug/`. @@ -58,7 +64,7 @@ The built APK will be located in `app_pojavlauncher/build/outputs/apk/debug/`. If you need more control over the build process, follow these steps: -1. **Java Runtime Environment (JRE):** Download the `jre8-pojav` artifact from our [CI auto builds](https://github.com/AngelAuraMC/openjdk-build-multiarch/actions). This package contains pre-built JREs for all supported architectures. If you need to build the JRE yourself, follow the instructions in the [android-openjdk-build-multiarch](https://github.com/AngelAuraMC/openjdk-build-multiarch) repository. +1. **Java Runtime Environment (JRE):** Download the `jre8-pojav` artifact from AngelAuraMCs [CI auto builds](https://github.com/AngelAuraMC/openjdk-build-multiarch/actions). This package contains pre-built JREs for all supported architectures. If you need to build the JRE yourself, follow the instructions in the [android-openjdk-build-multiarch](https://github.com/AngelAuraMC/openjdk-build-multiarch) repository. 2. **LWJGL:** The build instructions for the custom LWJGL are available over the [LWJGL repository](https://github.com/AngelAuraMC/lwjgl3). @@ -92,29 +98,24 @@ If you need more control over the build process, follow these steps: * [x] Game surface zooming * [x] New input pipe rewritten to native code * [x] Rewritten entire controls system -* [ ] More to come! +* [x] Added piracy support. +* [x] Added Sodium support. +* [x] Added new theme. +* [x] Added Krypton Wrapper. +* [x] Readded LTW. + ## Known Issues -See our [issue tracker](https://github.com/AngelAuraMC/Amethyst-Android/issues) for a list of known issues and their current status. - -## FAQ - -See our [wiki](https://wiki.angelauramc.dev/) for more information. - -## Contributing - -Contributions are welcome! We welcome any type of contribution, not only code. For example, you can help improve the [wiki](https://github.com/AngelAuraMC/angelauramc.github.io/), contribute to the [translations](https://crowdin.com/project/pojavlauncher), or submit bug reports and feature requests. - -Any code change should be submitted as a pull request. The description should explain what the code does and give steps to execute it. +See Copper's [issue tracker](https://github.com/CopperLauncher/CopperLauncher/issues) for a list of known issues and their current status. ## Support -For support, please join our [Discord server](https://discord.gg/5ptqkyZxEy). +For support, please join our [Discord server](https://dsc.gg/Copper-launcher) ## License -Amethyst is licensed under [GNU LGPLv3](https://github.com/AngelAuraMC/Amethyst-Android/blob/v3_openjdk/LICENSE). +Copper is licensed under [GNU LGPLv3](https://github.com/Copper-launcher/Copper-Android/blob/v3_openjdk/LICENSE). ## Credits & Dependencies @@ -123,7 +124,6 @@ Amethyst is licensed under [GNU LGPLv3](https://github.com/AngelAuraMC/Amethyst- * Android Support Libraries: [Apache License 2.0](https://android.googlesource.com/platform/prebuilts/maven_repo/android/+/master/NOTICE.txt). * [GL4ES](https://github.com/AngelAuraMC/gl4es): [MIT License](https://github.com/ptitSeb/gl4es/blob/master/LICENSE). * [MobileGlues](https://github.com/MobileGL-Dev/MobileGlues): [LGPL-2.1 License](https://github.com/MobileGL-Dev/MobileGlues/blob/dev-es/LICENSE). -* [Krypton Wrapper](https://github.com/BZLZHH/NG-GL4ES): [MIT License](https://github.com/BZLZHH/NG-GL4ES/blob/main/LICENSE) * [ANGLE](https://chromium.googlesource.com/angle/angle): [All Rights Reserved](app_pojavlauncher/src/main/assets/licenses/ANGLE_LICENSE). * [OpenJDK](https://github.com/AngelAuraMC/openjdk-multiarch-jdk8u): [GNU GPLv2 License](https://openjdk.java.net/legal/gplv2+ce.html). * [LWJGL3](https://github.com/AngelAuraMC/lwjgl3): [BSD-3 License](https://github.com/LWJGL/lwjgl3/blob/master/LICENSE.md). @@ -151,4 +151,4 @@ Future plans include: * Improving stability and performance. * Enhancing the mod installation experience. -We welcome community feedback and suggestions for our roadmap. Please feel free to open a feature request in our [issue tracker](https://github.com/AngelAuraMC/Amethyst-Android/issues). +We welcome community feedback and suggestions for our roadmap. Please feel free to open a feature request in our [issue tracker](https://github.com/Copper-launcher/Copper-Android/issues). diff --git a/app_pojavlauncher/aamc_upload.jks b/app_pojavlauncher/aamc_upload.jks index f66fdc77bb..1033b27ab7 100644 Binary files a/app_pojavlauncher/aamc_upload.jks and b/app_pojavlauncher/aamc_upload.jks differ diff --git a/app_pojavlauncher/build.gradle b/app_pojavlauncher/build.gradle index 2b7254dd21..681edba7ff 100644 --- a/app_pojavlauncher/build.gradle +++ b/app_pojavlauncher/build.gradle @@ -43,7 +43,7 @@ def getVersionName = { return ("LOCAL-" + "${getDate()}") }else { // Used by github actions - TAG_STRING = 'amethyst-legacy-' + "${getDate()}" + "-" + TAG_PART_COMMIT.toString().trim() + TAG_STRING = 'copper-legacy-' + "${getDate()}" + "-" + TAG_PART_COMMIT.toString().trim() } } @@ -100,7 +100,7 @@ android { } defaultConfig { - applicationId "org.angelauramc.amethyst" + applicationId "com.maxjubayeryt.copper" minSdkVersion 21 targetSdkVersion 34 versionCode 10000000 @@ -122,11 +122,11 @@ android { shrinkResources false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' signingConfig signingConfigs.customDebug - resValue "string", "app_name", "Amethyst (Debug)" - resValue "string", "app_short_name", "Amethyst (Debug)" - resValue 'string', 'application_package', 'org.angelauramc.amethyst.debug' - resValue 'string', 'storageProviderAuthorities', 'org.angelauramc.amethyst.scoped.gamefolder.debug' - resValue 'string', 'shareProviderAuthority', 'org.angelauramc.amethyst.scoped.controlfolder.debug' + resValue "string", "app_name", "Copper (Debug)" + resValue "string", "app_short_name", "Copper (Debug)" + resValue 'string', 'application_package', 'com.maxjubayeryt.copper.debug' + resValue 'string', 'storageProviderAuthorities', 'com.maxjubayeryt.copper.scoped.gamefolder.debug' + resValue 'string', 'shareProviderAuthority', 'com.maxjubayeryt.copper.scoped.controlfolder.debug' } proguard { initWith debug @@ -146,10 +146,10 @@ android { // defaultConfig already set // multiDexEnabled = true // debuggable = true - resValue "string", "app_name", "Amethyst" - resValue "string", "app_short_name", "Amethyst" - resValue 'string', 'storageProviderAuthorities', 'org.angelauramc.amethyst.scoped.gamefolder' - resValue 'string', 'application_package', 'org.angelauramc.amethyst' + resValue "string", "app_name", "Copper" + resValue "string", "app_short_name", "Copper" + resValue 'string', 'storageProviderAuthorities', 'com.maxjubayeryt.copper.gamefolder' + resValue 'string', 'application_package', 'com.maxjubayeryt.copper' } gplay { initWith release diff --git a/app_pojavlauncher/libs/HolyGL4ES-release.aar b/app_pojavlauncher/libs/HolyGL4ES-release.aar new file mode 100644 index 0000000000..bd9c13123e Binary files /dev/null and b/app_pojavlauncher/libs/HolyGL4ES-release.aar differ diff --git a/app_pojavlauncher/libs/krypton_wrapper-release.aar b/app_pojavlauncher/libs/krypton_wrapper-release.aar deleted file mode 100644 index fcb1223afe..0000000000 Binary files a/app_pojavlauncher/libs/krypton_wrapper-release.aar and /dev/null differ diff --git a/app_pojavlauncher/src/main/assets/amethyst.png b/app_pojavlauncher/src/main/assets/amethyst.png index 4e34d64565..42343f8595 100644 Binary files a/app_pojavlauncher/src/main/assets/amethyst.png and b/app_pojavlauncher/src/main/assets/amethyst.png differ diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java index c1929b1859..996edf58a8 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java @@ -455,13 +455,6 @@ private void runCraft(String versionId, JMinecraftVersionList.Version version) t } catch (NumberFormatException e) { folder.mkdir(); } MinecraftAccount minecraftAccount = PojavProfile.getCurrentProfileContent(this, null); - if (hasMods("sodium")) - Logger.appendToLog("WARNING: Sodium is being used, Amethyst-Android does NOT support this mod, you are on your own"); - Logger.appendToLog("--------- Starting game with Launcher Debug!"); - Tools.printLauncherInfo(versionId, Tools.isValidString(minecraftProfile.javaArgs) ? minecraftProfile.javaArgs : LauncherPreferences.PREF_CUSTOM_JAVA_ARGS); - if(Tools.LOCAL_RENDERER.equals("opengles_mobileglues")) { - LauncherPreferences.writeMGRendererSettings(); - } JREUtils.redirectAndPrintJRELog(); LauncherProfiles.load(); int requiredJavaVersion = 8; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java index 40f693f7d4..022b32690a 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java @@ -195,9 +195,7 @@ public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) { } @Override - public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) { - // TODO: Triggers on eglSwapBuffers. Add a loading message and make it end here - } + public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {} }); ((ViewGroup)getParent()).addView(textureView); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavApplication.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavApplication.java index 6a4972758c..dd7e770ff8 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavApplication.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavApplication.java @@ -39,7 +39,7 @@ public void onCreate() { // Write to file, since some devices may not able to show error FileUtils.ensureParentDirectory(crashFile); PrintStream crashStream = new PrintStream(crashFile); - crashStream.append("Amethyst crash report\n"); + crashStream.append("Copper crash report\n"); crashStream.append(" - Time: ").append(DateFormat.getDateTimeInstance().format(new Date())).append("\n"); crashStream.append(" - Device: ").append(Build.PRODUCT).append(" ").append(Build.MODEL).append("\n"); crashStream.append(" - Android version: ").append(Build.VERSION.RELEASE).append("\n"); 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 2f45c47aed..d79718ccd3 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -114,11 +114,11 @@ public final class Tools { public static final float BYTE_TO_MB = 1024 * 1024; public static final Handler MAIN_HANDLER = new Handler(Looper.getMainLooper()); - public static String APP_NAME = "Amethyst"; + public static String APP_NAME = "Copper"; public static final Gson GLOBAL_GSON = new GsonBuilder().setPrettyPrinting().create(); - public static final String URL_HOME = "https://wiki.angelauramc.dev"; + public static final String URL_HOME = "https://angelauramc.dev/wiki"; public static String NATIVE_LIB_DIR; public static String DIR_DATA; //Initialized later to get context public static File DIR_CACHE; @@ -131,7 +131,6 @@ public final class Tools { public static String DIR_ACCOUNT_NEW; public static String DIR_GAME_HOME = Environment.getExternalStorageDirectory().getAbsolutePath() + "/games/Amethyst"; public static String DIR_GAME_NEW; - public static String GAME_PROFILES_FILE; // New since 3.0.0 public static String DIRNAME_HOME_JRE = "lib"; @@ -217,8 +216,6 @@ public static void initStorageConstants(Context ctx){ OBSOLETE_RESOURCES_PATH = DIR_GAME_NEW + "/resources"; CTRLMAP_PATH = DIR_GAME_HOME + "/controlmap"; CTRLDEF_FILE = DIR_GAME_HOME + "/controlmap/default.json"; - GAME_PROFILES_FILE = Tools.DIR_GAME_NEW + "/launcher_profiles.json"; - switchDemo(isDemoProfile(ctx)); } @SuppressLint("PrivateApi") @@ -291,42 +288,6 @@ public static boolean hasMods(String... filenames) { 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. * @@ -781,7 +742,7 @@ public static String[] getMinecraftJVMArgs(String versionName, File gameDir) { } public static String[] getMinecraftClientArgs(MinecraftAccount profile, JMinecraftVersionList.Version versionInfo, File gameDir) { - String username = profile.username.replace("Demo.", ""); + String username = profile.username; String versionName = versionInfo.id; if (versionInfo.inheritsFrom != null) { versionName = versionInfo.inheritsFrom; @@ -826,13 +787,13 @@ public static String[] getMinecraftClientArgs(MinecraftAccount profile, JMinecra } } - String mcArguments = versionInfo.minecraftArguments == null ? - fromStringArray(minecraftArgs.toArray(new String[0])): - versionInfo.minecraftArguments; - - if(profile.isDemo()) mcArguments += " --demo"; - - return JSONUtils.insertJSONValueList(splitAndFilterEmpty(mcArguments), varArgMap); + return JSONUtils.insertJSONValueList( + splitAndFilterEmpty( + versionInfo.minecraftArguments == null ? + fromStringArray(minecraftArgs.toArray(new String[0])): + versionInfo.minecraftArguments + ), varArgMap + ); } public static String fromStringArray(String[] strArr) { @@ -1774,11 +1735,7 @@ public static void dialogForceClose(Context ctx) { } public static void switchDemo(boolean isDemo){ - if(isDemo) { - DIR_GAME_NEW = DIR_DATA + "/demo/.minecraft"; - } else { - DIR_GAME_NEW = DIR_GAME_HOME + "/.minecraft"; - } + DIR_GAME_NEW = DIR_GAME_HOME + "/.minecraft"; DIR_HOME_VERSION = DIR_GAME_NEW + "/versions"; DIR_HOME_LIBRARY = DIR_GAME_NEW + "/libraries"; ASSETS_PATH = DIR_GAME_NEW + "/assets"; @@ -1798,8 +1755,7 @@ public static boolean isOnline(Context ctx) { } public static boolean isDemoProfile(Context ctx){ - MinecraftAccount currentProfile = PojavProfile.getCurrentProfileContent(ctx, null); - return currentProfile != null && currentProfile.isDemo(); + return false; } public static boolean isLocalProfile(Context ctx){ @@ -1807,12 +1763,7 @@ public static boolean isLocalProfile(Context ctx){ return currentProfile == null || currentProfile.isLocal(); } public static boolean hasOnlineProfile(){ - for (MinecraftAccount accountToCheck : getAllProfiles()) { - if (!accountToCheck.isLocal() && !accountToCheck.isDemo()) { - return true; - } - } - return false; + return true; } public static void hasNoOnlineProfileDialog(Activity activity, @Nullable Runnable run, @Nullable String customTitle, @Nullable String customMessage){ diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/microsoft/MicrosoftBackgroundLogin.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/microsoft/MicrosoftBackgroundLogin.java index 351c6e2685..297b4da75d 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/microsoft/MicrosoftBackgroundLogin.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/microsoft/MicrosoftBackgroundLogin.java @@ -87,15 +87,17 @@ public void performLogin(@Nullable final ProgressListener progressListener, MinecraftAccount acc = MinecraftAccount.load(mcName); if(acc == null) acc = new MinecraftAccount(); - acc.xuid = xsts[0]; - acc.clientToken = "0"; /* FIXME */ - acc.accessToken = mcToken; - acc.username = mcName; - acc.profileId = mcUuid; - acc.isMicrosoft = true; - acc.msaRefreshToken = msRefreshToken; - acc.expiresAt = expiresAt; - acc.updateSkinFace(); + if (doesOwnGame) { + acc.xuid = xsts[0]; + acc.clientToken = "0"; /* FIXME */ + acc.accessToken = mcToken; + acc.username = mcName; + acc.profileId = mcUuid; + acc.isMicrosoft = true; + acc.msaRefreshToken = msRefreshToken; + acc.expiresAt = expiresAt; + acc.updateSkinFace(); + } acc.save(); if(doneListener != null) { @@ -296,9 +298,7 @@ private void checkMcProfile(String mcAccessToken) throws IOException, JSONExcept }else{ Log.i("MicrosoftLogin","It seems that this Microsoft Account does not own the game."); doesOwnGame = false; - mcName = "Demo.Player"; - mcUuid = "00000000-0000-0000-0000-000000000000"; - //throw new PresentedException(new RuntimeException(conn.getResponseMessage()), R.string.minecraft_not_owned); + throw new PresentedException(new RuntimeException(conn.getResponseMessage()), R.string.minecraft_not_owned); //throwResponseError(conn); } } 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 3c55940a4e..4bb93ac42e 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,13 +1,10 @@ package net.kdt.pojavlaunch.fragments; -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.app.Dialog; import android.content.Intent; import android.os.Bundle; import android.view.View; @@ -17,7 +14,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; import com.kdt.mcgui.mcVersionSpinner; @@ -39,75 +35,93 @@ public class MainMenuFragment extends Fragment { private mcVersionSpinner mVersionSpinner; - public MainMenuFragment(){ + public MainMenuFragment() { super(R.layout.fragment_launcher); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - Button mNewsButton = view.findViewById(R.id.news_button); - Button mDiscordButton = view.findViewById(R.id.discord_button); - Button mCustomControlButton = view.findViewById(R.id.custom_control_button); - Button mInstallJarButton = view.findViewById(R.id.install_jar_button); - Button mShareLogsButton = view.findViewById(R.id.share_logs_button); - Button mOpenDirectoryButton = view.findViewById(R.id.open_files_button); + Button mNewsButton = view.findViewById(R.id.news_button); + Button mDiscordButton = view.findViewById(R.id.discord_button); + Button mCustomControlButton = view.findViewById(R.id.custom_control_button); + Button mInstallJarButton = view.findViewById(R.id.install_jar_button); + Button mShareLogsButton = view.findViewById(R.id.share_logs_button); + Button mManageModsButton = view.findViewById(R.id.open_files_button); + Button mOpenDirectoryButton = view.findViewById(R.id.open_directory_button); + Button mModStoreButton = view.findViewById(R.id.mod_store_button); ImageButton mEditProfileButton = view.findViewById(R.id.edit_profile_button); Button mPlayButton = view.findViewById(R.id.play_button); mVersionSpinner = view.findViewById(R.id.mc_version_spinner); + // Wiki mNewsButton.setOnClickListener(v -> Tools.openURL(requireActivity(), Tools.URL_HOME)); + + // Discord mDiscordButton.setOnClickListener(v -> Tools.openURL(requireActivity(), getString(R.string.discord_invite))); - mCustomControlButton.setOnClickListener(v -> startActivity(new Intent(requireContext(), CustomControlsActivity.class))); + + // Custom controls + mCustomControlButton.setOnClickListener(v -> + startActivity(new Intent(requireContext(), CustomControlsActivity.class))); + + // Mod Store → individual mod search + if (mModStoreButton != null) + mModStoreButton.setOnClickListener(v -> + Tools.swapFragment(requireActivity(), ModsSearchFragment.class, ModsSearchFragment.TAG, null)); + + // Execute .jar 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 -> { - 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); - - - }); - - mShareLogsButton.setOnClickListener((v) -> shareLog(requireContext())); - - mOpenDirectoryButton.setOnClickListener((v)-> { - 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); + } else { + mInstallJarButton.setOnClickListener(v -> hasNoOnlineProfileDialog(requireActivity())); + } + + // Share logs + if (mShareLogsButton != null) + mShareLogsButton.setOnClickListener(v -> shareLog(requireContext())); + + // Manage Mods & Tools → new UI + mManageModsButton.setOnClickListener(v -> + Tools.swapFragment(requireActivity(), ManageModsFragment.class, ManageModsFragment.TAG, null)); + + // Open game directory (original behaviour) + if (mOpenDirectoryButton != null) { + mOpenDirectoryButton.setOnClickListener(v -> { + if (Tools.isDemoProfile(v.getContext())) { + hasNoOnlineProfileDialog(getActivity(), + getString(R.string.demo_unsupported), getString(R.string.change_account)); + } else if (!hasOnlineProfile()) { + hasNoOnlineProfileDialog(requireActivity()); + } else { + openPath(v.getContext(), getCurrentProfileDirectory(), false); + } + }); + } - }); + // Edit profile + mEditProfileButton.setOnClickListener(v -> mVersionSpinner.openProfileEditor(requireActivity())); + // Play + mPlayButton.setOnClickListener(v -> ExtraCore.setValue(ExtraConstants.LAUNCH_GAME, true)); - mNewsButton.setOnLongClickListener((v)->{ + // Long-press wiki → gamepad mapper (hidden) + mNewsButton.setOnLongClickListener(v -> { Tools.swapFragment(requireActivity(), GamepadMapperFragment.class, GamepadMapperFragment.TAG, null); return true; }); } private File getCurrentProfileDirectory() { - String currentProfile = LauncherPreferences.DEFAULT_PREF.getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE, null); - if(!Tools.isValidString(currentProfile)) return new File(Tools.DIR_GAME_NEW); + String currentProfile = LauncherPreferences.DEFAULT_PREF + .getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE, null); + if (!Tools.isValidString(currentProfile)) return new File(Tools.DIR_GAME_NEW); LauncherProfiles.load(); MinecraftProfile profileObject = LauncherProfiles.mainProfileJson.profiles.get(currentProfile); - if(profileObject == null) return new File(Tools.DIR_GAME_NEW); + if (profileObject == null) return new File(Tools.DIR_GAME_NEW); return Tools.getGameDirPath(profileObject); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ManageModsFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ManageModsFragment.java new file mode 100644 index 0000000000..57b620947f --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ManageModsFragment.java @@ -0,0 +1,95 @@ +package net.kdt.pojavlaunch.fragments; + +import android.os.Bundle; +import android.view.View; +import android.widget.ImageButton; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import net.kdt.pojavlaunch.R; +import net.kdt.pojavlaunch.fragments.ModsSearchFragment; +import net.kdt.pojavlaunch.Tools; +import net.kdt.pojavlaunch.modloaders.InstalledModAdapter; +import net.kdt.pojavlaunch.prefs.LauncherPreferences; +import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles; +import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile; + +import java.io.File; + +public class ManageModsFragment extends Fragment { + + public static final String TAG = "ManageModsFragment"; + + public ManageModsFragment() { + super(R.layout.fragment_manage_mods); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + ImageButton backButton = view.findViewById(R.id.manage_mods_back); + ImageButton addButton = view.findViewById(R.id.manage_mods_add); + TextView title = view.findViewById(R.id.manage_mods_title); + RecyclerView recycler = view.findViewById(R.id.manage_mods_recycler); + View emptyState = view.findViewById(R.id.manage_mods_empty); + + // Back + backButton.setOnClickListener(v -> Tools.removeCurrentFragment(requireActivity())); + + // Add → open mod store + addButton.setOnClickListener(v -> + Tools.swapFragment(requireActivity(), ModsSearchFragment.class, ModsSearchFragment.TAG, null)); + + // Title: "ProfileName - Mods" + String profileName = getCurrentProfileName(); + title.setText(profileName.isEmpty() + ? getString(R.string.mcl_button_manage_mods) + : profileName + " - Mods"); + + // Build mod list + File modsDir = getModsDir(); + InstalledModAdapter adapter = new InstalledModAdapter(modsDir, isEmpty -> { + recycler.setVisibility(isEmpty ? View.GONE : View.VISIBLE); + emptyState.setVisibility(isEmpty ? View.VISIBLE : View.GONE); + }); + + recycler.setLayoutManager(new LinearLayoutManager(requireContext())); + recycler.setAdapter(adapter); + } + + // ── Helpers ───────────────────────────────────────────────────────────── + + private String getCurrentProfileName() { + try { + String key = LauncherPreferences.DEFAULT_PREF + .getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE, null); + if (key == null || key.isEmpty()) return ""; + LauncherProfiles.load(); + MinecraftProfile profile = LauncherProfiles.mainProfileJson.profiles.get(key); + if (profile == null) return ""; + return profile.name != null ? profile.name : key; + } catch (Exception e) { + return ""; + } + } + + private File getModsDir() { + try { + String key = LauncherPreferences.DEFAULT_PREF + .getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE, null); + if (key != null && !key.isEmpty()) { + LauncherProfiles.load(); + MinecraftProfile profile = LauncherProfiles.mainProfileJson.profiles.get(key); + if (profile != null) { + File gameDir = Tools.getGameDirPath(profile); + return new File(gameDir, "mods"); + } + } + } catch (Exception ignored) {} + return new File(Tools.DIR_GAME_NEW, "mods"); + } +} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ModsSearchFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ModsSearchFragment.java new file mode 100644 index 0000000000..ed67b67037 --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ModsSearchFragment.java @@ -0,0 +1,402 @@ +package net.kdt.pojavlaunch.fragments; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.Color; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import android.widget.Toast; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ProgressBar; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.core.math.MathUtils; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.kdt.mcgui.ProgressLayout; + +import net.kdt.pojavlaunch.PojavApplication; +import net.kdt.pojavlaunch.R; +import net.kdt.pojavlaunch.Tools; +import net.kdt.pojavlaunch.modloaders.modpacks.ModItemAdapter; +import net.kdt.pojavlaunch.modloaders.modpacks.api.CommonApi; +import net.kdt.pojavlaunch.modloaders.modpacks.api.ModpackApi; +import net.kdt.pojavlaunch.modloaders.modpacks.api.ModrinthApi; +import net.kdt.pojavlaunch.modloaders.modpacks.models.ModDetail; +import net.kdt.pojavlaunch.modloaders.modpacks.models.ModItem; +import net.kdt.pojavlaunch.modloaders.modpacks.models.SearchFilters; +import net.kdt.pojavlaunch.modloaders.modpacks.models.Constants; +import net.kdt.pojavlaunch.prefs.LauncherPreferences; +import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper; +import net.kdt.pojavlaunch.profiles.VersionSelectorDialog; +import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles; +import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile; +import net.kdt.pojavlaunch.utils.DownloadUtils; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Searches and installs individual mods into the current instance's mods folder. + * - Version filter: when an MC version is selected, only versions matching it are shown. + * - Dependency dialog: shown before download, matching the ModBundle UI. + */ +public class ModsSearchFragment extends Fragment implements ModItemAdapter.SearchResultCallback { + + public static final String TAG = "ModsSearchFragment"; + + private View mOverlay; + private float mOverlayTopCache; + + private final RecyclerView.OnScrollListener mOverlayPositionListener = new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + mOverlay.setY(MathUtils.clamp(mOverlay.getY() - dy, -mOverlay.getHeight(), mOverlayTopCache)); + } + }; + + private EditText mSearchEditText; + private ImageButton mFilterButton; + private RecyclerView mRecyclerview; + private ModItemAdapter mModItemAdapter; + private ProgressBar mSearchProgressBar; + private TextView mStatusTextView; + private ColorStateList mDefaultTextColor; + + private ModpackApi mModpackApi; + private final SearchFilters mSearchFilters; + + public ModsSearchFragment() { + super(R.layout.fragment_mod_search); + mSearchFilters = new SearchFilters(); + mSearchFilters.isModpack = false; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + mModpackApi = new ModsInstallApi(context.getString(R.string.curseforge_api_key), mSearchFilters); + ((ModsInstallApi) mModpackApi).mActivityContext = context; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + mModItemAdapter = new ModItemAdapter(getResources(), mModpackApi, this); + ProgressKeeper.addTaskCountListener(mModItemAdapter); + mOverlayTopCache = getResources().getDimension(R.dimen.fragment_padding_medium); + + mOverlay = view.findViewById(R.id.search_mod_overlay); + mSearchEditText = view.findViewById(R.id.search_mod_edittext); + mSearchProgressBar = view.findViewById(R.id.search_mod_progressbar); + mRecyclerview = view.findViewById(R.id.search_mod_list); + mStatusTextView = view.findViewById(R.id.search_mod_status_text); + mFilterButton = view.findViewById(R.id.search_mod_filter); + + mDefaultTextColor = mStatusTextView.getTextColors(); + + mRecyclerview.setLayoutManager(new LinearLayoutManager(getContext())); + mRecyclerview.setAdapter(mModItemAdapter); + mRecyclerview.addOnScrollListener(mOverlayPositionListener); + + mSearchEditText.setOnEditorActionListener((v, actionId, event) -> { + searchMods(mSearchEditText.getText().toString()); + mSearchEditText.clearFocus(); + return false; + }); + + mOverlay.post(() -> { + int overlayHeight = mOverlay.getHeight(); + mRecyclerview.setPadding( + mRecyclerview.getPaddingLeft(), + mRecyclerview.getPaddingTop() + overlayHeight, + mRecyclerview.getPaddingRight(), + mRecyclerview.getPaddingBottom()); + }); + + mFilterButton.setOnClickListener(v -> displayFilterDialog()); + mSearchEditText.setHint(R.string.hint_search_mod); + searchMods(null); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + ProgressKeeper.removeTaskCountListener(mModItemAdapter); + mRecyclerview.removeOnScrollListener(mOverlayPositionListener); + } + + @Override + public void onSearchFinished() { + mSearchProgressBar.setVisibility(View.GONE); + mStatusTextView.setVisibility(View.GONE); + } + + @Override + public void onSearchError(int error) { + mSearchProgressBar.setVisibility(View.GONE); + mStatusTextView.setVisibility(View.VISIBLE); + switch (error) { + case ERROR_INTERNAL: + mStatusTextView.setTextColor(Color.RED); + mStatusTextView.setText(R.string.search_mod_error); + break; + case ERROR_NO_RESULTS: + mStatusTextView.setTextColor(mDefaultTextColor); + mStatusTextView.setText(R.string.search_mod_no_result); + break; + } + } + + private void searchMods(String name) { + mSearchProgressBar.setVisibility(View.VISIBLE); + mSearchFilters.name = name == null ? "" : name; + mModItemAdapter.performSearchQuery(mSearchFilters); + } + + private void displayFilterDialog() { + AlertDialog dialog = new AlertDialog.Builder(requireContext()) + .setView(R.layout.dialog_mod_filters) + .create(); + + dialog.setOnShowListener(dialogInterface -> { + TextView mSelectedVersion = dialog.findViewById(R.id.search_mod_selected_mc_version_textview); + Button mSelectVersionButton = dialog.findViewById(R.id.search_mod_mc_version_button); + Button mApplyButton = dialog.findViewById(R.id.search_mod_apply_filters); + + assert mSelectedVersion != null; + assert mSelectVersionButton != null; + assert mApplyButton != null; + + mSelectVersionButton.setOnClickListener(v -> + VersionSelectorDialog.open(v.getContext(), true, + (id, snapshot) -> mSelectedVersion.setText(id))); + + mSelectedVersion.setText(mSearchFilters.mcVersion); + + mApplyButton.setOnClickListener(v -> { + mSearchFilters.mcVersion = mSelectedVersion.getText().toString(); + searchMods(mSearchEditText.getText().toString()); + dialogInterface.dismiss(); + }); + }); + + dialog.show(); + } + + // ── ModsInstallApi ──────────────────────────────────────────────────────── + + private static class ModsInstallApi extends CommonApi { + + private final SearchFilters mFilters; + private final ModrinthApi mModrinthApi = new ModrinthApi(); + private final Handler mMainHandler = new Handler(Looper.getMainLooper()); + private Context mActivityContext; + + ModsInstallApi(String curseforgeApiKey, SearchFilters filters) { + super(curseforgeApiKey); + mFilters = filters; + } + + /** + * Override getModDetails to filter versions by the selected MC version. + * Only versions matching the filter are shown in the version dropdown. + */ + @Override + public ModDetail getModDetails(ModItem item) { + if (item.apiSource == net.kdt.pojavlaunch.modloaders.modpacks.models.Constants.SOURCE_MODRINTH) { + String filterVer = (mFilters.mcVersion != null && !mFilters.mcVersion.isEmpty()) + ? mFilters.mcVersion : null; + return mModrinthApi.getModDetails(item, filterVer); + } + return super.getModDetails(item); + } + + @Override + public void handleInstallation(Context context, ModDetail modDetail, int selectedVersion) { + if (modDetail.isModpack) { + super.handleInstallation(context, modDetail, selectedVersion); + return; + } + + String url = modDetail.versionUrls[selectedVersion]; + + // Check if this is a CF-restricted mod using the flag set during search + boolean isCfRestricted = modDetail.apiSource == Constants.SOURCE_CURSEFORGE + && (modDetail.isRestricted || url == null || url.isEmpty()); + + if (isCfRestricted) { + // Show dialog directing user to download from CurseForge website + String cfUrl = "https://www.curseforge.com/minecraft/mc-mods/" + modDetail.id; + Context dialogCtx = mActivityContext != null ? mActivityContext : context; + mMainHandler.post(() -> + new AlertDialog.Builder(dialogCtx) + .setTitle(modDetail.title) + .setMessage("This mod restricts third-party downloads.\n\nDownload it manually from CurseForge and place it in your mods folder:\n\n" + cfUrl) + .setPositiveButton("Open CurseForge", (d, w) -> + Tools.openURL((android.app.Activity) dialogCtx, cfUrl)) + .setNegativeButton(android.R.string.cancel, null) + .show() + ); + return; + } + + if (url == null || url.isEmpty()) { + Tools.showErrorRemote(context, R.string.modpack_install_download_failed, + new IOException("No download URL available for this mod")); + return; + } + + // Extract filename + String rawName = url.substring(url.lastIndexOf('/') + 1); + if (rawName.contains("?")) rawName = rawName.substring(0, rawName.indexOf('?')); + final String fileName = rawName.endsWith(".jar") ? rawName : rawName + ".jar"; + + // Check if this version has dependencies + String[] depIds = (modDetail.versionDependencyIds != null) ? modDetail.versionDependencyIds[selectedVersion] : null; + String[] depTypes = (modDetail.versionDependencyTypes != null) ? modDetail.versionDependencyTypes[selectedVersion] : null; + + if (depIds == null || depIds.length == 0) { + // No deps — download directly + downloadMod(context, url, fileName, new String[0], new String[0]); + return; + } + + // Fetch project names for all deps, then show dialog + String[] labels = new String[depIds.length]; + final boolean[] checkedDefaults = new boolean[depIds.length]; + AtomicInteger remaining = new AtomicInteger(depIds.length); + + for (int i = 0; i < depIds.length; i++) { + final int idx = i; + final String type = (depTypes != null && idx < depTypes.length) ? depTypes[idx] : "required"; + final String prefix = "required".equals(type) ? "Required: " : "Optional: "; + checkedDefaults[idx] = "required".equals(type); + + final String projectId = depIds[idx]; + PojavApplication.sExecutorService.execute(() -> { + // Fetch project name from Modrinth + String name = fetchProjectName(projectId); + labels[idx] = prefix + (name != null ? name : projectId); + if (remaining.decrementAndGet() == 0) { + mMainHandler.post(() -> showDepsDialog(context, url, fileName, + depIds, depTypes, labels, checkedDefaults)); + } + }); + } + } + + private void showDepsDialog(Context context, String url, String fileName, + String[] depIds, String[] depTypes, + String[] labels, boolean[] checkedDefaults) { + // context here is getApplicationContext() from ModItemAdapter — no window token. + // Use the stored Activity reference instead. + Context dialogCtx = mActivityContext != null ? mActivityContext : context; + boolean[] selected = checkedDefaults.clone(); + + new AlertDialog.Builder(dialogCtx) + .setTitle(R.string.mod_deps_title) + .setMultiChoiceItems(labels, selected, + (dialog, which, isChecked) -> selected[which] = isChecked) + .setPositiveButton(R.string.mod_deps_install_selected, (d, w) -> { + List selectedIds = new ArrayList<>(); + for (int i = 0; i < depIds.length; i++) { + if (selected[i]) selectedIds.add(depIds[i]); + } + downloadMod(context, url, fileName, + selectedIds.toArray(new String[0]), depTypes); + }) + .setNeutralButton(R.string.mod_deps_install_without, + (d, w) -> downloadMod(context, url, fileName, new String[0], new String[0])) + .setNegativeButton(android.R.string.cancel, null) + .show(); + } + + private void downloadMod(Context context, String url, String fileName, + String[] depIds, String[] depTypes) { + File modsDir = getModsDir(); + if (!modsDir.exists()) modsDir.mkdirs(); + + ProgressLayout.setProgress(ProgressLayout.INSTALL_MODPACK, 0, R.string.global_waiting); + PojavApplication.sExecutorService.execute(() -> { + try { + // Download main mod + DownloadUtils.downloadFile(url, new File(modsDir, fileName)); + + // Download selected dependencies + for (String depId : depIds) { + if (depId == null || depId.isEmpty()) continue; + downloadDependency(depId, modsDir); + } + + ProgressLayout.clearProgress(ProgressLayout.INSTALL_MODPACK); + Tools.runOnUiThread(() -> + Toast.makeText(context, + context.getString(R.string.mod_install_success, fileName), + Toast.LENGTH_LONG).show()); + } catch (Exception e) { + ProgressLayout.clearProgress(ProgressLayout.INSTALL_MODPACK); + Tools.showErrorRemote(context, R.string.modpack_install_download_failed, e); + } + }); + } + + private void downloadDependency(String projectId, File modsDir) { + // Fetch latest version for the current MC version/loader filter + try { + String filterVer = (mFilters.mcVersion != null && !mFilters.mcVersion.isEmpty()) + ? mFilters.mcVersion : ""; + ModItem depItem = new ModItem( + net.kdt.pojavlaunch.modloaders.modpacks.models.Constants.SOURCE_MODRINTH, + false, projectId, projectId, "", ""); + ModDetail depDetail = mModrinthApi.getModDetails(depItem, filterVer.isEmpty() ? null : filterVer); + if (depDetail == null || depDetail.versionUrls == null || depDetail.versionUrls.length == 0) return; + + String depUrl = depDetail.versionUrls[0]; + String depName = depUrl.substring(depUrl.lastIndexOf('/') + 1); + if (depName.contains("?")) depName = depName.substring(0, depName.indexOf('?')); + if (!depName.endsWith(".jar")) depName += ".jar"; + + DownloadUtils.downloadFile(depUrl, new File(modsDir, depName)); + } catch (Exception e) { + Log.w(TAG, "Failed to download dependency " + projectId + ": " + e.getMessage()); + } + } + + private String fetchProjectName(String projectId) { + try { + net.kdt.pojavlaunch.modloaders.modpacks.api.ApiHandler handler = + new net.kdt.pojavlaunch.modloaders.modpacks.api.ApiHandler("https://api.modrinth.com/v2"); + com.google.gson.JsonObject obj = handler.get("project/" + projectId, + com.google.gson.JsonObject.class); + if (obj != null && obj.has("title")) return obj.get("title").getAsString(); + } catch (Exception ignored) {} + return null; + } + + private static File getModsDir() { + try { + String key = LauncherPreferences.DEFAULT_PREF + .getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE, null); + if (key != null && !key.isEmpty()) { + LauncherProfiles.load(); + MinecraftProfile profile = LauncherProfiles.mainProfileJson.profiles.get(key); + if (profile != null) return new File(Tools.getGameDirPath(profile), "mods"); + } + } catch (Exception ignored) {} + return new File(Tools.DIR_GAME_NEW, "mods"); + } + } +} \ No newline at end of file diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/InstalledModAdapter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/InstalledModAdapter.java new file mode 100644 index 0000000000..68a81977e7 --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/InstalledModAdapter.java @@ -0,0 +1,367 @@ +package net.kdt.pojavlaunch.modloaders; + +import android.app.AlertDialog; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +import net.kdt.pojavlaunch.PojavApplication; +import net.kdt.pojavlaunch.R; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +public class InstalledModAdapter extends RecyclerView.Adapter { + + private static final String TAG = "ModAdapter"; + + public interface EmptyStateListener { + void onEmptyStateChanged(boolean isEmpty); + } + + private final List mMods = new ArrayList<>(); + private final EmptyStateListener mEmptyListener; + private final Handler mMainHandler = new Handler(Looper.getMainLooper()); + + public InstalledModAdapter(File modsDir, EmptyStateListener listener) { + mEmptyListener = listener; + if (modsDir != null && modsDir.isDirectory()) { + File[] files = modsDir.listFiles(f -> f.isFile() && + (f.getName().endsWith(".jar") || f.getName().endsWith(".jar.disabled"))); + if (files != null) { + Arrays.sort(files, (a, b) -> a.getName().compareToIgnoreCase(b.getName())); + for (File f : files) mMods.add(new ModEntry(f)); + } + } + notifyEmptyState(); + } + + @NonNull + @Override + public ModViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_installed_mod, parent, false); + return new ModViewHolder(v); + } + + @Override + public void onBindViewHolder(@NonNull ModViewHolder holder, int position) { + holder.bind(mMods.get(position)); + } + + @Override + public void onViewRecycled(@NonNull ModViewHolder holder) { + // Clear the tag so any in-flight load doesn't update this recycled view + holder.icon.setTag(null); + holder.icon.setImageResource(R.drawable.ic_add_modded); + super.onViewRecycled(holder); + } + + @Override + public int getItemCount() { return mMods.size(); } + + private void notifyEmptyState() { + if (mEmptyListener != null) mEmptyListener.onEmptyStateChanged(mMods.isEmpty()); + } + + // ── ViewHolder ──────────────────────────────────────────────────────── + + class ModViewHolder extends RecyclerView.ViewHolder { + final ImageView icon; + final TextView name, version; + final SwitchCompat toggle; + final ImageButton delete; + + ModViewHolder(@NonNull View itemView) { + super(itemView); + icon = itemView.findViewById(R.id.installed_mod_icon); + name = itemView.findViewById(R.id.installed_mod_name); + version = itemView.findViewById(R.id.installed_mod_version); + toggle = itemView.findViewById(R.id.installed_mod_toggle); + delete = itemView.findViewById(R.id.installed_mod_delete); + } + + void bind(ModEntry entry) { + name.setText(entry.displayName()); + version.setText(entry.file.getName()); + + // Tag the ImageView with the file path so we can verify it hasn't been recycled + icon.setTag(entry.file.getAbsolutePath()); + icon.setImageResource(R.drawable.ic_add_modded); + + final String expectedTag = entry.file.getAbsolutePath(); + final WeakReference iconRef = new WeakReference<>(icon); + final File jarFile = entry.file; + + PojavApplication.sExecutorService.execute(() -> { + Bitmap bmp = extractModIcon(jarFile); + if (bmp == null) return; + mMainHandler.post(() -> { + ImageView iv = iconRef.get(); + // Only update if the view still belongs to the same mod + if (iv != null && expectedTag.equals(iv.getTag())) { + iv.setImageBitmap(bmp); + } + }); + }); + + toggle.setOnCheckedChangeListener(null); + toggle.setChecked(entry.enabled); + toggle.setOnCheckedChangeListener((btn, checked) -> entry.setEnabled(checked)); + + delete.setOnClickListener(v -> { + Context ctx = v.getContext(); + new AlertDialog.Builder(ctx) + .setTitle(ctx.getString(R.string.manage_mods_delete_confirm, entry.displayName())) + .setNegativeButton(android.R.string.cancel, null) + .setPositiveButton(android.R.string.ok, (d, i) -> { + entry.file.delete(); + int p = getBindingAdapterPosition(); + if (p != RecyclerView.NO_POSITION) { + mMods.remove(p); + notifyItemRemoved(p); + notifyEmptyState(); + } + }) + .show(); + }); + } + } + + // ── ModEntry ────────────────────────────────────────────────────────── + + static class ModEntry { + File file; + boolean enabled; + + ModEntry(File f) { + this.file = f; + this.enabled = !f.getName().endsWith(".disabled"); + } + + String displayName() { + String n = file.getName(); + if (n.endsWith(".jar.disabled")) n = n.substring(0, n.length() - 13); + else if (n.endsWith(".jar")) n = n.substring(0, n.length() - 4); + return n; + } + + void setEnabled(boolean enable) { + if (enable == this.enabled) return; + File target = enable + ? new File(file.getParent(), file.getName().replace(".jar.disabled", ".jar")) + : new File(file.getParent(), file.getName() + ".disabled"); + if (file.renameTo(target)) { + file = target; + this.enabled = enable; + } + } + } + + // ── Icon extraction ─────────────────────────────────────────────────── + + @Nullable + private static Bitmap extractModIcon(File jarFile) { + try (ZipFile zip = new ZipFile(jarFile)) { + String iconPath = resolveIconPath(zip); + Log.d(TAG, jarFile.getName() + " → icon path: " + iconPath); + + if (iconPath != null) { + Bitmap bmp = loadEntryAsBitmap(zip, iconPath); + if (bmp != null) return bmp; + Log.w(TAG, "Icon path resolved but bitmap failed: " + iconPath); + } + + // Fallback scan — some old mods don't declare icon in metadata + for (String fallback : new String[]{"pack.png", "icon.png", "logo.png"}) { + Bitmap bmp = loadEntryAsBitmap(zip, fallback); + if (bmp != null) return bmp; + } + } catch (Exception e) { + Log.w(TAG, "Failed to open JAR: " + jarFile.getName() + " — " + e.getMessage()); + } + return null; + } + + @Nullable + private static String resolveIconPath(ZipFile zip) { + // 1. Fabric — fabric.mod.json → "icon" (string OR {"64":"path"} object) + String content = readEntry(zip, "fabric.mod.json"); + if (content != null) { + try { + JsonObject obj = JsonParser.parseString(content).getAsJsonObject(); + if (obj.has("icon")) { + JsonElement iconEl = obj.get("icon"); + if (iconEl.isJsonPrimitive()) { + return iconEl.getAsString(); + } else if (iconEl.isJsonObject()) { + // Size map e.g. {"64": "path64.png", "128": "path128.png"} + // Pick the largest available + JsonObject sizeMap = iconEl.getAsJsonObject(); + String best = null; + int bestSize = 0; + for (String key : sizeMap.keySet()) { + try { + int sz = Integer.parseInt(key); + if (sz > bestSize) { + bestSize = sz; + best = sizeMap.get(key).getAsString(); + } + } catch (NumberFormatException ignored) { + best = sizeMap.get(key).getAsString(); + } + } + if (best != null) return best; + } + } + } catch (Exception e) { + Log.w(TAG, "fabric.mod.json parse error: " + e.getMessage()); + } + } + + // 2. Quilt — quilt.mod.json → quilt_loader.metadata.icon + content = readEntry(zip, "quilt.mod.json"); + if (content != null) { + try { + JsonObject root = JsonParser.parseString(content).getAsJsonObject(); + JsonObject ql = root.has("quilt_loader") ? + root.getAsJsonObject("quilt_loader") : null; + if (ql != null && ql.has("metadata")) { + JsonObject meta = ql.getAsJsonObject("metadata"); + if (meta.has("icon") && meta.get("icon").isJsonPrimitive()) + return meta.get("icon").getAsString(); + } + } catch (Exception e) { + Log.w(TAG, "quilt.mod.json parse error: " + e.getMessage()); + } + } + + // 3. Forge legacy — mcmod.info → logoFile + content = readEntry(zip, "mcmod.info"); + if (content != null) { + try { + // mcmod.info is a JSON array + JsonArray arr = JsonParser.parseString(content).getAsJsonArray(); + if (arr.size() > 0 && arr.get(0).isJsonObject()) { + JsonObject mod = arr.get(0).getAsJsonObject(); + if (mod.has("logoFile")) { + String logo = mod.get("logoFile").getAsString(); + if (!logo.isEmpty()) return logo; + } + } + } catch (Exception e) { + Log.w(TAG, "mcmod.info parse error: " + e.getMessage()); + } + } + + // 4. Forge/NeoForge — TOML — logoFile = "path" + for (String toml : new String[]{"META-INF/neoforge.mods.toml", "META-INF/mods.toml"}) { + content = readEntry(zip, toml); + if (content != null) { + String logo = tomlStringField(content, "logoFile"); + if (logo != null && !logo.isEmpty()) return logo; + } + } + + return null; + } + + // ── Low-level helpers ───────────────────────────────────────────────── + + /** + * Load a ZipEntry as a Bitmap. + * IMPORTANT: BitmapFactory.decodeStream needs mark/reset support. + * ZipInputStream doesn't support it, so we buffer all bytes first. + */ + @Nullable + private static Bitmap loadEntryAsBitmap(ZipFile zip, String entryPath) { + // ZipFile.getEntry is case-sensitive — try exact then case-insensitive scan + ZipEntry entry = zip.getEntry(entryPath); + if (entry == null) { + // Case-insensitive fallback + String lower = entryPath.toLowerCase(); + Enumeration entries = zip.entries(); + while (entries.hasMoreElements()) { + ZipEntry e = entries.nextElement(); + if (e.getName().toLowerCase().equals(lower)) { + entry = e; + break; + } + } + } + if (entry == null) return null; + + try (InputStream is = zip.getInputStream(entry)) { + // Buffer into byte array — BitmapFactory needs mark/reset + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buf = new byte[8192]; + int read; + while ((read = is.read(buf)) != -1) baos.write(buf, 0, read); + byte[] bytes = baos.toByteArray(); + return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); + } catch (Exception e) { + Log.w(TAG, "loadEntryAsBitmap failed for " + entryPath + ": " + e.getMessage()); + return null; + } + } + + @Nullable + private static String readEntry(ZipFile zip, String entryPath) { + ZipEntry entry = zip.getEntry(entryPath); + if (entry == null) return null; + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(zip.getInputStream(entry), "UTF-8"))) { + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) sb.append(line).append('\n'); + return sb.toString(); + } catch (Exception e) { + return null; + } + } + + @Nullable + private static String tomlStringField(String toml, String field) { + for (String line : toml.split("\n")) { + line = line.trim(); + if (line.startsWith(field + " ") || line.startsWith(field + "=")) { + int eq = line.indexOf('='); + if (eq < 0) continue; + String val = line.substring(eq + 1).trim(); + if (val.startsWith("\"") && val.endsWith("\"")) + val = val.substring(1, val.length() - 1); + if (!val.isEmpty()) return val; + } + } + return null; + } +} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/CurseforgeApi.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/CurseforgeApi.java index cb4c17ab18..7036f3c9e5 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/CurseforgeApi.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/CurseforgeApi.java @@ -78,16 +78,17 @@ public SearchResult searchMod(SearchFilters searchFilters, SearchResult previous JsonElement allowModDistribution = dataElement.get("allowModDistribution"); // Gson automatically casts null to false, which leans to issues // So, only check the distribution flag if it is non-null - if(!allowModDistribution.isJsonNull() && !allowModDistribution.getAsBoolean()) { - Log.i("CurseforgeApi", "Skipping modpack "+dataElement.get("name").getAsString() + " because curseforge sucks"); - continue; - } + boolean restricted = !allowModDistribution.isJsonNull() && !allowModDistribution.getAsBoolean(); + JsonObject logo = dataElement.getAsJsonObject("logo"); + String thumbnailUrl = (logo != null && logo.has("thumbnailUrl") && !logo.get("thumbnailUrl").isJsonNull()) + ? logo.get("thumbnailUrl").getAsString() : ""; ModItem modItem = new ModItem(Constants.SOURCE_CURSEFORGE, searchFilters.isModpack, dataElement.get("id").getAsString(), dataElement.get("name").getAsString(), dataElement.get("summary").getAsString(), - dataElement.getAsJsonObject("logo").get("thumbnailUrl").getAsString()); + thumbnailUrl); + modItem.isRestricted = restricted; modItemList.add(modItem); } if(curseforgeSearchResult == null) curseforgeSearchResult = new CurseforgeSearchResult(); @@ -100,6 +101,14 @@ public SearchResult searchMod(SearchFilters searchFilters, SearchResult previous @Override public ModDetail getModDetails(ModItem item) { + // Short-circuit for restricted mods — no point fetching versions + if (item.isRestricted) { + return new ModDetail(item, + new String[]{"Blocked by the author!"}, + new String[]{null}, + new String[]{null}, + new String[]{null}); + } ArrayList allModDetails = new ArrayList<>(); int index = 0; while(index != CURSEFORGE_PAGINATION_END_REACHED && @@ -108,6 +117,26 @@ public ModDetail getModDetails(ModItem item) { } if(index == CURSEFORGE_PAGINATION_ERROR) return null; int length = allModDetails.size(); + + // Check if ALL versions have null downloadUrl (fully restricted mod) + boolean allRestricted = length > 0; + for (int i = 0; i < length; i++) { + JsonElement url = allModDetails.get(i).get("downloadUrl"); + if (url != null && !url.isJsonNull()) { + allRestricted = false; + break; + } + } + if (allRestricted || length == 0) { + // All versions restricted - return a ModDetail with one entry that signals this. + // The version name shown in spinner makes it clear, tapping Install shows CF dialog. + return new ModDetail(item, + new String[]{"Blocked by the author! By clicking the install button it will open the CurseForge page."}, + new String[]{null}, + new String[]{null}, + new String[]{null}); + } + String[] versionNames = new String[length]; String[] mcVersionNames = new String[length]; String[] versionUrls = new String[length]; @@ -117,7 +146,11 @@ public ModDetail getModDetails(ModItem item) { versionNames[i] = modDetail.get("displayName").getAsString(); JsonElement downloadUrl = modDetail.get("downloadUrl"); - versionUrls[i] = downloadUrl.getAsString(); + if (downloadUrl == null || downloadUrl.isJsonNull()) { + versionUrls[i] = null; + } else { + versionUrls[i] = downloadUrl.getAsString(); + } JsonArray gameVersions = modDetail.getAsJsonArray("gameVersions"); for(JsonElement jsonElement : gameVersions) { @@ -282,4 +315,4 @@ private boolean verifyManifest(CurseManifest manifest) { static class CurseforgeSearchResult extends SearchResult { int previousOffset; } -} +} \ No newline at end of file diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/ModrinthApi.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/ModrinthApi.java index 3253366247..de799fb348 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/ModrinthApi.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/api/ModrinthApi.java @@ -86,32 +86,73 @@ public SearchResult searchMod(SearchFilters searchFilters, SearchResult previous @Override public ModDetail getModDetails(ModItem item) { + return getModDetails(item, null); + } + public ModDetail getModDetails(ModItem item, String filterMcVersion) { JsonArray response = mApiHandler.get(String.format("project/%s/version", item.id), JsonArray.class); if(response == null) return null; - System.out.println(response); - String[] names = new String[response.size()]; - String[] mcNames = new String[response.size()]; - String[] urls = new String[response.size()]; - String[] hashes = new String[response.size()]; - - for (int i=0; i versions = new java.util.ArrayList<>(); + for (int i = 0; i < response.size(); i++) { + JsonObject v = response.get(i).getAsJsonObject(); + if (filterMcVersion != null && !filterMcVersion.isEmpty()) { + JsonArray gameVersions = v.get("game_versions").getAsJsonArray(); + boolean matches = false; + for (int j = 0; j < gameVersions.size(); j++) { + if (filterMcVersion.equals(gameVersions.get(j).getAsString())) { + matches = true; + break; + } + } + if (!matches) continue; + } + versions.add(v); + } + + if (versions.isEmpty()) return null; + + int size = versions.size(); + String[] names = new String[size]; + String[] mcNames = new String[size]; + String[] urls = new String[size]; + String[] hashes = new String[size]; + String[][] depIds = new String[size][]; + String[][] depTypes = new String[size][]; + + for (int i = 0; i < size; i++) { + JsonObject version = versions.get(i); + names[i] = version.get("name").getAsString(); mcNames[i] = version.get("game_versions").getAsJsonArray().get(0).getAsString(); - urls[i] = version.get("files").getAsJsonArray().get(0).getAsJsonObject().get("url").getAsString(); - // Assume there may not be hashes, in case the API changes + urls[i] = version.get("files").getAsJsonArray().get(0).getAsJsonObject().get("url").getAsString(); + JsonObject hashesMap = version.getAsJsonArray("files").get(0).getAsJsonObject() .get("hashes").getAsJsonObject(); - if(hashesMap == null || hashesMap.get("sha1") == null){ - hashes[i] = null; - continue; + hashes[i] = (hashesMap == null || hashesMap.get("sha1") == null) ? null + : hashesMap.get("sha1").getAsString(); + + // Capture dependencies + if (version.has("dependencies") && !version.get("dependencies").isJsonNull()) { + JsonArray deps = version.getAsJsonArray("dependencies"); + java.util.List ids = new java.util.ArrayList<>(); + java.util.List types = new java.util.ArrayList<>(); + for (int j = 0; j < deps.size(); j++) { + JsonObject dep = deps.get(j).getAsJsonObject(); + if (dep.has("project_id") && !dep.get("project_id").isJsonNull()) { + ids.add(dep.get("project_id").getAsString()); + types.add(dep.has("dependency_type") ? dep.get("dependency_type").getAsString() : "required"); + } + } + depIds[i] = ids.toArray(new String[0]); + depTypes[i] = types.toArray(new String[0]); + } else { + depIds[i] = new String[0]; + depTypes[i] = new String[0]; } - - hashes[i] = hashesMap.get("sha1").getAsString(); } - return new ModDetail(item, names, mcNames, urls, hashes); + return new ModDetail(item, names, mcNames, urls, hashes, depIds, depTypes); } @Override diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/models/ModDetail.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/models/ModDetail.java index 5a54e78b75..6bc3abc404 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/models/ModDetail.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/models/ModDetail.java @@ -12,16 +12,28 @@ public class ModDetail extends ModItem { public String[] versionUrls; /* SHA 1 hashes, null if a hash is unavailable */ public String[] versionHashes; + /* Per-version dependency project IDs */ + public String[][] versionDependencyIds; + /* Per-version dependency types — "required" or "optional" */ + public String[][] versionDependencyTypes; + public ModDetail(ModItem item, String[] versionNames, String[] mcVersionNames, String[] versionUrls, String[] hashes) { + this(item, versionNames, mcVersionNames, versionUrls, hashes, null, null); + } + + public ModDetail(ModItem item, String[] versionNames, String[] mcVersionNames, String[] versionUrls, String[] hashes, + String[][] depIds, String[][] depTypes) { super(item.apiSource, item.isModpack, item.id, item.title, item.description, item.imageUrl); this.versionNames = versionNames; this.mcVersionNames = mcVersionNames; this.versionUrls = versionUrls; this.versionHashes = hashes; + this.versionDependencyIds = depIds; + this.versionDependencyTypes = depTypes; // Add the mc version to the version model for (int i=0; i= 0 && number < units.length) { - return units[number]; - } else { - throw new IllegalArgumentException("This function only works for numbers 0 to 10"); - } - } - - @Override - protected void onClick() { - if (isChecked()) { // Don't ask for braincells if turning off - super.onClick(); - return; - } - - Random random = new Random(); - int a = random.nextInt(10) + 1; - int b = random.nextInt(10) + 1; - int c = random.nextInt(10) + 1; - int d = random.nextInt(10) + 1; - final int answer = (a * b) + c - d; - final Context ctx = getContext(); - final EditText input = new EditText(ctx); - input.setInputType(InputType.TYPE_NUMBER_FLAG_SIGNED | InputType.TYPE_CLASS_NUMBER); - - mathDialog = new AlertDialog.Builder(ctx) - .setTitle(R.string.sodium_math_warning_title) - .setMessage(ctx.getString(R.string.sodium_math_warning_message, intToWord(a), intToWord(b), intToWord(c), intToWord(d))) - .setView(input) - .setPositiveButton(ctx.getText(android.R.string.ok), (dialog, which) -> { - try { - int userAnswer = Integer.parseInt(input.getText().toString()); - if (userAnswer == answer) { - super.onClick(); - } else { - dialog(ctx, "Wrong!", "You failed the math test!"); - } - } catch (NumberFormatException e) { - Toast.makeText(ctx, "Please enter a number.", Toast.LENGTH_SHORT).show(); - } - }) - .setNegativeButton("Cancel", null) - .show(); - - Button positiveButton = mathDialog.getButton(DialogInterface.BUTTON_POSITIVE); - positiveButton.setEnabled(false); - int waitTime = 45; - new CountDownTimer(waitTime * 1000L, 1000L) { - @Override - public void onTick(long millisUntilFinished) { - long secondsLeft = (millisUntilFinished / 1000) + 1; - positiveButton.setText(String.format(Locale.ROOT, "%s(%d)", ctx.getString(android.R.string.ok), secondsLeft)); - } - - @Override - public void onFinish() { - positiveButton.setText(ctx.getString(android.R.string.ok)); - positiveButton.setEnabled(true); - } - }.start(); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java index acd14e3978..1b0eb01f66 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java @@ -495,22 +495,23 @@ public static String loadGraphicsLibrary(){ case "opengles2": case "opengles2_5": case "opengles3": - renderLibrary = "libng_gl4es.so"; break; + renderLibrary = "libgl4es_115.so"; break; case "vulkan_zink": renderLibrary = "libOSMesa.so"; break; case "opengles_mobileglues": renderLibrary = "libmobileglues.so"; break; - case "opengles3_desktopgl_zink_kopper": renderLibrary = "libglxshim.so"; break; + case "opengles3_desktopgl_zink": renderLibrary = "libglxshim.so"; break; case "opengles3_ltw" : renderLibrary = "libltw.so"; break; + case "opengles3_KW" : renderLibrary = "libng_gl4es.so"; break; default: Log.w("RENDER_LIBRARY", "No renderer selected, defaulting to opengles2"); - renderLibrary = "libng_gl4es.so"; + renderLibrary = "libgl4es_115.so"; break; } if (!dlopen(renderLibrary) && !dlopen(findInLdLibPath(renderLibrary))) { - Log.e("RENDER_LIBRARY","Failed to load renderer " + renderLibrary + ". Falling back to Krypton Wrapper"); + Log.e("RENDER_LIBRARY","Failed to load renderer " + renderLibrary + ". Falling back to GL4ES 1.1.4"); LOCAL_RENDERER = "opengles2"; - renderLibrary = "libng_gl4es.so"; - dlopen(NATIVE_LIB_DIR + "/libng_gl4es.so"); + renderLibrary = "libgl4es_115.so"; + dlopen(NATIVE_LIB_DIR + "/libgl4es_115.so"); } return renderLibrary; } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/TouchControllerUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/TouchControllerUtils.java index c999a283e3..e5bbb7bd6b 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/TouchControllerUtils.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/TouchControllerUtils.java @@ -25,7 +25,7 @@ private TouchControllerUtils() { } public static LauncherProxyClient proxyClient; - private static final String socketName = "Amethyst"; + private static final String socketName = "Copper"; private static class VibrationHandler implements LauncherProxyClient.VibrationHandler { private final Vibrator vibrator; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/MinecraftAccount.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/MinecraftAccount.java index daf857deee..9757202dc9 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/MinecraftAccount.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/MinecraftAccount.java @@ -46,11 +46,11 @@ void updateSkinFace(String uuid) { } public boolean isLocal(){ - return accessToken.equals("0") && !username.startsWith("Demo."); + return false; } public boolean isDemo(){ - return username.startsWith("Demo."); + return false; } public void updateSkinFace() { diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/LauncherProfiles.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/LauncherProfiles.java index 1b477d53e0..e13c9d83d5 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/LauncherProfiles.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/LauncherProfiles.java @@ -16,7 +16,7 @@ public class LauncherProfiles { public static MinecraftLauncherProfiles mainProfileJson; - private static final File launcherProfilesFile = new File(Tools.GAME_PROFILES_FILE); + private static final File launcherProfilesFile = new File(Tools.DIR_GAME_NEW, "launcher_profiles.json"); /** Reload the profile from the file, creating a default one if necessary */ public static void load(){ diff --git a/app_pojavlauncher/src/main/res/drawable/ic_add_modded.xml b/app_pojavlauncher/src/main/res/drawable/ic_add_modded.xml index 70046c48fe..314541ede4 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_add_modded.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_add_modded.xml @@ -1,5 +1,16 @@ - - + + + + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_arrow_back_white.xml b/app_pojavlauncher/src/main/res/drawable/ic_arrow_back_white.xml index 9b1f144be3..f2a900d97f 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_arrow_back_white.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_arrow_back_white.xml @@ -1,9 +1,5 @@ - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_edit_profile.xml b/app_pojavlauncher/src/main/res/drawable/ic_edit_profile.xml index 3ef0fa8147..eee27ff9f9 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_edit_profile.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_edit_profile.xml @@ -1,9 +1,5 @@ - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_file.xml b/app_pojavlauncher/src/main/res/drawable/ic_file.xml index 925742e17c..c34d7d0173 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_file.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_file.xml @@ -1,21 +1,5 @@ - - - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_folder.xml b/app_pojavlauncher/src/main/res/drawable/ic_folder.xml index 7934923e93..86f75248e1 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_folder.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_folder.xml @@ -1,21 +1,5 @@ - - - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_folder_managed.xml b/app_pojavlauncher/src/main/res/drawable/ic_folder_managed.xml new file mode 100644 index 0000000000..04d51c2511 --- /dev/null +++ b/app_pojavlauncher/src/main/res/drawable/ic_folder_managed.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_menu_custom_controls.xml b/app_pojavlauncher/src/main/res/drawable/ic_menu_custom_controls.xml index 952facc3ad..f99c68f848 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_menu_custom_controls.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_menu_custom_controls.xml @@ -1,41 +1,5 @@ - - - - - - - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_menu_delete_forever.xml b/app_pojavlauncher/src/main/res/drawable/ic_menu_delete_forever.xml index 36f9aa4d4a..6d297fb891 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_menu_delete_forever.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_menu_delete_forever.xml @@ -1,9 +1,9 @@ + android:viewportWidth="24" + android:viewportHeight="24"> + android:pathData="M16,2v4h6v2h-2v14L4,22L4,8L2,8L2,6h6L8,2zM14,4h-4v2h4zM14,8L6,8v12h12L18,8zM9,10h2v8L9,18zM15,10h-2v8h2z" + android:fillColor="#FFF"/> diff --git a/app_pojavlauncher/src/main/res/drawable/ic_menu_home.xml b/app_pojavlauncher/src/main/res/drawable/ic_menu_home.xml index 5023206d29..948bc4fe2c 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_menu_home.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_menu_home.xml @@ -1,9 +1,5 @@ - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_menu_install_jar.xml b/app_pojavlauncher/src/main/res/drawable/ic_menu_install_jar.xml index b8bb942269..cb9089f288 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_menu_install_jar.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_menu_install_jar.xml @@ -1,30 +1,5 @@ - - - - - - - - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_menu_news.xml b/app_pojavlauncher/src/main/res/drawable/ic_menu_news.xml index 9b0f209a44..dae0e581af 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_menu_news.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_menu_news.xml @@ -1,21 +1,5 @@ - - - - - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_menu_settings.xml b/app_pojavlauncher/src/main/res/drawable/ic_menu_settings.xml index fc5bc048bc..84f9caa3ac 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_menu_settings.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_menu_settings.xml @@ -1,9 +1,5 @@ - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_menu_share.xml b/app_pojavlauncher/src/main/res/drawable/ic_menu_share.xml new file mode 100644 index 0000000000..04d51c2511 --- /dev/null +++ b/app_pojavlauncher/src/main/res/drawable/ic_menu_share.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_mg_renderer_styled.xml b/app_pojavlauncher/src/main/res/drawable/ic_mg_renderer_styled.xml new file mode 100644 index 0000000000..eb25d2f87a --- /dev/null +++ b/app_pojavlauncher/src/main/res/drawable/ic_mg_renderer_styled.xml @@ -0,0 +1,9 @@ + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_pojav_full.webp b/app_pojavlauncher/src/main/res/drawable/ic_pojav_full.webp index 7680d0769a..0f9590dda0 100644 Binary files a/app_pojavlauncher/src/main/res/drawable/ic_pojav_full.webp and b/app_pojavlauncher/src/main/res/drawable/ic_pojav_full.webp differ diff --git a/app_pojavlauncher/src/main/res/drawable/ic_setting_control_scale.xml b/app_pojavlauncher/src/main/res/drawable/ic_setting_control_scale.xml index 5477c4f4e4..e53f36f39a 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_setting_control_scale.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_setting_control_scale.xml @@ -1,20 +1,9 @@ - - + android:width="120dp"> + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_setting_engine.xml b/app_pojavlauncher/src/main/res/drawable/ic_setting_engine.xml index c460fc1c84..eb25d2f87a 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_setting_engine.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_setting_engine.xml @@ -1,46 +1,9 @@ + android:width="120dp" + android:height="120dp" + android:viewportWidth="24" + android:viewportHeight="24"> - - - - - + android:pathData="M18,0h2v4h4v2h-2v2h-2v2h-2L18,6h-4L14,4h2L16,2h2zM4,3h8v2L4,5v14h16v-7h2v9L2,21L2,3zM14,9h-2v2h-2v2L8,13v2L6,15v2h2v-2h2v-2h2v-2h2v2h2v2h2v-2h-2v-2h-2zM8,7L6,7v2h2z" + android:fillColor="#FFFFFF"/> diff --git a/app_pojavlauncher/src/main/res/drawable/ic_setting_gesture_disable.xml b/app_pojavlauncher/src/main/res/drawable/ic_setting_gesture_disable.xml index 724aacb39d..9fe77b64e0 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_setting_gesture_disable.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_setting_gesture_disable.xml @@ -1,38 +1,9 @@ + android:width="120dp" + android:height="120dp" + android:viewportWidth="21" + android:viewportHeight="21"> - - - - + android:pathData="M8.05,1.5h1.63v1.64h1.64v6.54h6.54v1.64h-6.54L11.32,9.68L9.68,9.68L9.68,3.14L8.05,3.14v11.45L6.4,14.59v-1.64L4.77,12.95v-1.63L3.14,11.32v3.27h1.63v1.64h1.64v1.63h4.9v1.64h-4.9v-1.64L4.77,17.86v-1.63L3.14,16.23v-1.64L1.5,14.59v-3.27h1.64L3.14,9.68h1.63v1.64h1.64L6.41,3.14h1.64L8.05,1.5zM12.95,3.14h4.91v1.63h-4.9L12.96,3.14zM12.95,6.41h3.28v1.64h-3.28L12.95,6.4zM14.59,14.59h1.64v1.64h1.63v-1.64h1.64v1.64h-1.64v1.63h1.64v1.64h-1.64v-1.64h-1.63v1.64h-1.64v-1.64h1.64v-1.63h-1.64v-1.64z" + android:fillColor="#FFFFFF" /> diff --git a/app_pojavlauncher/src/main/res/drawable/ic_setting_gesture_time.xml b/app_pojavlauncher/src/main/res/drawable/ic_setting_gesture_time.xml index f8f6c4dd8a..5ba18d50d7 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_setting_gesture_time.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_setting_gesture_time.xml @@ -1,26 +1,5 @@ - - - - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_setting_hash_verification.xml b/app_pojavlauncher/src/main/res/drawable/ic_setting_hash_verification.xml index ee33460a8b..e301ce4b4b 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_setting_hash_verification.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_setting_hash_verification.xml @@ -1,38 +1,5 @@ - - - - - - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_setting_hide_notch.xml b/app_pojavlauncher/src/main/res/drawable/ic_setting_hide_notch.xml index ae37ba2f26..07d403ab80 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_setting_hide_notch.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_setting_hide_notch.xml @@ -1,20 +1,5 @@ - - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_setting_java_runtime.xml b/app_pojavlauncher/src/main/res/drawable/ic_setting_java_runtime.xml index 3292e346c1..fdcc1a3366 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_setting_java_runtime.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_setting_java_runtime.xml @@ -1,26 +1,5 @@ - - - - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_setting_misc.xml b/app_pojavlauncher/src/main/res/drawable/ic_setting_misc.xml index f349e7d63a..384f80051a 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_setting_misc.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_setting_misc.xml @@ -1,31 +1,5 @@ - - - - - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_setting_mouse_speed.xml b/app_pojavlauncher/src/main/res/drawable/ic_setting_mouse_speed.xml index 7bc0fc838b..c441a77d7f 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_setting_mouse_speed.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_setting_mouse_speed.xml @@ -1,54 +1,5 @@ - - - - - - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_setting_pointer_scale.xml b/app_pojavlauncher/src/main/res/drawable/ic_setting_pointer_scale.xml index a15ba8a72e..d6b64d2e10 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_setting_pointer_scale.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_setting_pointer_scale.xml @@ -1,46 +1,5 @@ - - - - - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_setting_ram.xml b/app_pojavlauncher/src/main/res/drawable/ic_setting_ram.xml index b9c81c2249..a70db2fcb9 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_setting_ram.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_setting_ram.xml @@ -1,9 +1,5 @@ - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_setting_screen_resolution.xml b/app_pojavlauncher/src/main/res/drawable/ic_setting_screen_resolution.xml index e1deaaeb79..b2463816ca 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_setting_screen_resolution.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_setting_screen_resolution.xml @@ -1,16 +1,9 @@ + android:width="120dp" + android:height="120dp" + android:viewportWidth="24" + android:viewportHeight="24"> - + android:pathData="M2,4h20v16H2zm2,14h16V6H4zM8,8h2v2H8v2H6V8zm8,8h-2v-2h2v-2h2v4z" + android:fillColor="#FFFFFF"/> diff --git a/app_pojavlauncher/src/main/res/drawable/ic_setting_video.xml b/app_pojavlauncher/src/main/res/drawable/ic_setting_video.xml index 4dbfe93647..3df95ba02e 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_setting_video.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_setting_video.xml @@ -1,16 +1,5 @@ - - - + + + + diff --git a/app_pojavlauncher/src/main/res/drawable/ic_sharp_settings_24.xml b/app_pojavlauncher/src/main/res/drawable/ic_sharp_settings_24.xml index 6ac42d86dd..6d4bcd25f0 100644 --- a/app_pojavlauncher/src/main/res/drawable/ic_sharp_settings_24.xml +++ b/app_pojavlauncher/src/main/res/drawable/ic_sharp_settings_24.xml @@ -1,5 +1,5 @@ - + diff --git a/app_pojavlauncher/src/main/res/drawable/mine_button_unfocused.9.png b/app_pojavlauncher/src/main/res/drawable/mine_button_unfocused.9.png index 96a6d5f6a6..2c237ddd50 100644 Binary files a/app_pojavlauncher/src/main/res/drawable/mine_button_unfocused.9.png and b/app_pojavlauncher/src/main/res/drawable/mine_button_unfocused.9.png differ diff --git a/app_pojavlauncher/src/main/res/drawable/storage_alert.xml b/app_pojavlauncher/src/main/res/drawable/storage_alert.xml index 3b5f2d80da..18c11c9722 100644 --- a/app_pojavlauncher/src/main/res/drawable/storage_alert.xml +++ b/app_pojavlauncher/src/main/res/drawable/storage_alert.xml @@ -1,5 +1,5 @@ - + diff --git a/app_pojavlauncher/src/main/res/layout-land/fragment_launcher.xml b/app_pojavlauncher/src/main/res/layout-land/fragment_launcher.xml index 3cf2f0b6a3..ded29b0e21 100644 --- a/app_pojavlauncher/src/main/res/layout-land/fragment_launcher.xml +++ b/app_pojavlauncher/src/main/res/layout-land/fragment_launcher.xml @@ -2,12 +2,9 @@ + + + + + + + app:layout_constraintTop_toBottomOf="@id/mod_store_button"/> + + + + + app:layout_constraintTop_toBottomOf="@id/open_directory_button"/> + app:layout_constraintTop_toBottomOf="@id/install_jar_button"/> - app:layout_constraintTop_toBottomOf="@id/share_logs_button" /> - - - - - @@ -140,8 +156,6 @@ android:id="@+id/play_button" android:layout_width="0dp" android:layout_height="wrap_content" - - android:layout_marginEnd="@dimen/_8sdp" android:text="@string/main_play" android:textAllCaps="true" @@ -150,4 +164,3 @@ app:layout_constraintTop_toTopOf="@+id/mc_version_spinner" /> - diff --git a/app_pojavlauncher/src/main/res/layout/activity_pojav_launcher.xml b/app_pojavlauncher/src/main/res/layout/activity_pojav_launcher.xml index b4d20e0378..cd011b9934 100644 --- a/app_pojavlauncher/src/main/res/layout/activity_pojav_launcher.xml +++ b/app_pojavlauncher/src/main/res/layout/activity_pojav_launcher.xml @@ -10,10 +10,8 @@ android:id="@+id/account_spinner" android:layout_width="match_parent" android:layout_height="@dimen/_52sdp" - android:dropDownWidth="@dimen/_250sdp" android:dropDownVerticalOffset="@dimen/_52sdp" - app:layout_constraintTop_toTopOf="parent" /> - - - - - \ No newline at end of file + diff --git a/app_pojavlauncher/src/main/res/layout/fragment_launcher.xml b/app_pojavlauncher/src/main/res/layout/fragment_launcher.xml index ad6f7229d1..3cf9d3a9e7 100644 --- a/app_pojavlauncher/src/main/res/layout/fragment_launcher.xml +++ b/app_pojavlauncher/src/main/res/layout/fragment_launcher.xml @@ -1,142 +1,200 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/fragment_menu_main" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/background_app"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - diff --git a/app_pojavlauncher/src/main/res/layout/fragment_manage_mods.xml b/app_pojavlauncher/src/main/res/layout/fragment_manage_mods.xml new file mode 100644 index 0000000000..0b3ded9e97 --- /dev/null +++ b/app_pojavlauncher/src/main/res/layout/fragment_manage_mods.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app_pojavlauncher/src/main/res/layout/item_installed_mod.xml b/app_pojavlauncher/src/main/res/layout/item_installed_mod.xml new file mode 100644 index 0000000000..85ec97f470 --- /dev/null +++ b/app_pojavlauncher/src/main/res/layout/item_installed_mod.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app_pojavlauncher/src/main/res/layout/view_mod.xml b/app_pojavlauncher/src/main/res/layout/view_mod.xml index cfca0a84a2..fb01be89a6 100644 --- a/app_pojavlauncher/src/main/res/layout/view_mod.xml +++ b/app_pojavlauncher/src/main/res/layout/view_mod.xml @@ -5,35 +5,34 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@drawable/background_line" - android:paddingHorizontal="@dimen/_2sdp" - android:paddingVertical="@dimen/_2sdp" + android:background="@drawable/background_card" android:layout_marginVertical="@dimen/padding_medium" - > + android:foreground="?attr/selectableItemBackground" + android:clickable="true" + android:focusable="true"> + - tools:src="@mipmap/ic_launcher_foreground" - /> - + + tools:src="@drawable/ic_modrinth" /> + + tools:text="Sodium" /> + + tools:text="The fastest and most compatible rendering optimization mod for Minecraft." /> - - - - + app:layout_constraintTop_toBottomOf="@id/mod_thumbnail_imageview" /> - \ No newline at end of file + diff --git a/app_pojavlauncher/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app_pojavlauncher/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 4ae7d12378..cb73a95729 100644 --- a/app_pojavlauncher/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app_pojavlauncher/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -2,4 +2,4 @@ - \ No newline at end of file + diff --git a/app_pojavlauncher/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app_pojavlauncher/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 4ae7d12378..cb73a95729 100644 --- a/app_pojavlauncher/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app_pojavlauncher/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -2,4 +2,4 @@ - \ No newline at end of file + diff --git a/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher.webp b/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher.webp index 113c1e4a21..3b3ec9ecc1 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher.webp and b/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher_background.webp b/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher_background.webp index 8a5807c16a..23d22ae6f3 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher_background.webp and b/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher_background.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp index 4c721c777e..37f307f697 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp and b/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher_round.webp index 113c1e4a21..3b3ec9ecc1 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher_round.webp and b/app_pojavlauncher/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher.webp b/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher.webp index 807284e975..61e7eb44d7 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher.webp and b/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher_background.webp b/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher_background.webp index 593db40d89..421182f7a1 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher_background.webp and b/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher_background.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp index 2ad568e85d..9dff2faf38 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp and b/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher_round.webp index 807284e975..61e7eb44d7 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher_round.webp and b/app_pojavlauncher/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher.webp index 0b6dd5b368..b891e01376 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher.webp and b/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher_background.webp b/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher_background.webp index 3e99e91e5f..9a3bc559a9 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher_background.webp and b/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher_background.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp b/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp index 0bc6b56f8d..b913848ae7 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp and b/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher_round.webp index 0b6dd5b368..b891e01376 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and b/app_pojavlauncher/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher.webp index 12b7f2bca4..ca69087413 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher.webp and b/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher_background.webp b/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher_background.webp index 2d1076728c..f97aae2866 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher_background.webp and b/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher_background.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp index 8554c67202..c5e2ac03a9 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp and b/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp index 12b7f2bca4..ca69087413 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and b/app_pojavlauncher/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher.webp index 400e6b22d6..a4e5858dcc 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and b/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher_background.webp b/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher_background.webp index 8a6631fab4..823e7e8984 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher_background.webp and b/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher_background.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp index 48a2de9fdd..d2c577ce84 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp and b/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp differ diff --git a/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp index 400e6b22d6..a18e07839a 100644 Binary files a/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and b/app_pojavlauncher/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/app_pojavlauncher/src/main/res/values-af/strings.xml b/app_pojavlauncher/src/main/res/values-af/strings.xml index dbb002b8a7..cbb6bcfd08 100644 --- a/app_pojavlauncher/src/main/res/values-af/strings.xml +++ b/app_pojavlauncher/src/main/res/values-af/strings.xml @@ -11,7 +11,7 @@ Wahlweise einen Mod-Installer - Amethyst ist unerwartet abgestürzt + Copper ist unerwartet abgestürzt Keine Version! Mehr anzeigen Weniger anzeigen diff --git a/app_pojavlauncher/src/main/res/values-ar/strings.xml b/app_pojavlauncher/src/main/res/values-ar/strings.xml index 300843dac8..4246069841 100644 --- a/app_pojavlauncher/src/main/res/values-ar/strings.xml +++ b/app_pojavlauncher/src/main/res/values-ar/strings.xml @@ -13,7 +13,7 @@ حدد مشغل مودات لتثبيته - لقد توقف Amethyst بشكل غير متوقع + لقد توقف Copper بشكل غير متوقع لا يوجد إصدار! اظهر المزيد أظهِر أقل @@ -186,7 +186,7 @@ العارض يفعل أوشحه من Cosmetica, (المعروفة مسبقًا ب Arc). لمزيد من المعلومات، يرجى زيارة https://cosmetica.cc, يتطلب Optifine لكي يعمل. عام - خدمة Amethyst في المقدمة + خدمة Copper في المقدمة مثبت (استخدم الافتراضي العام) مخطط التحكم الأفتراضي diff --git a/app_pojavlauncher/src/main/res/values-az-rAZ/strings.xml b/app_pojavlauncher/src/main/res/values-az-rAZ/strings.xml index dde1f38ea5..fc81699262 100644 --- a/app_pojavlauncher/src/main/res/values-az-rAZ/strings.xml +++ b/app_pojavlauncher/src/main/res/values-az-rAZ/strings.xml @@ -11,7 +11,7 @@ Mod quraşdırıcısını seçin - Amethyst gözlənilmədən çökdü + Copper gözlənilmədən çökdü Versiya yoxdur! Daha çox göstər Daha az göstər @@ -149,7 +149,7 @@ Sil Cosmetica-dan (əvvəllər Arc) qapaqları işə salır. Əlavə məlumat üçün https://cosmetica.cc saytına daxil olun. OptiFine tələb edir. Ümumi - Amethyst Önplan Xidməti + Copper Önplan Xidməti (Qlobal defoltdan istifadə edin) Defolt controlmap %d tapşırıq davam edir diff --git a/app_pojavlauncher/src/main/res/values-ba/strings.xml b/app_pojavlauncher/src/main/res/values-ba/strings.xml index 3058b64140..ab563c4aba 100644 --- a/app_pojavlauncher/src/main/res/values-ba/strings.xml +++ b/app_pojavlauncher/src/main/res/values-ba/strings.xml @@ -11,7 +11,7 @@ Мода ҡуйыусыһын һайлағыҙ - Көтмәгәндә Amethyst программаһының эше боҙолоп китә + Көтмәгәндә Copper программаһының эше боҙолоп китә Версиялар юҡ! Күберәк Әҙерәк diff --git a/app_pojavlauncher/src/main/res/values-bn-rBD/strings.xml b/app_pojavlauncher/src/main/res/values-bn-rBD/strings.xml index c237fbe2ad..727e7c4680 100644 --- a/app_pojavlauncher/src/main/res/values-bn-rBD/strings.xml +++ b/app_pojavlauncher/src/main/res/values-bn-rBD/strings.xml @@ -11,7 +11,7 @@ একটি মোড ইনস্টলার নির্বাচন করুন - Amethyst অপ্রত্যাশিতভাবে ক্র্যাশ হয়েছে + Copper অপ্রত্যাশিতভাবে ক্র্যাশ হয়েছে কোন ভার্সন নেই! আরো দেখুন কম দেখান diff --git a/app_pojavlauncher/src/main/res/values-ca/strings.xml b/app_pojavlauncher/src/main/res/values-ca/strings.xml index 187bdf3fd8..c1b770c647 100644 --- a/app_pojavlauncher/src/main/res/values-ca/strings.xml +++ b/app_pojavlauncher/src/main/res/values-ca/strings.xml @@ -11,7 +11,7 @@ Selecciona un mod per afegir - Amethyst s’ha parat inesperadament + Copper s’ha parat inesperadament Cap versio! Mostra més Mostrar menys @@ -94,7 +94,7 @@ Runtime de Java Renderitzador Activa les capes de Cosmetica (anteriorment Arc). Per a més informació visiteu https://cosmetica.cc. Requereix l\'OptiFine. - Servei de primer plà del Amethyst + Servei de primer plà del Copper (Usa el valor global per defecte) Mapa de control per defecte %d tasques en procés diff --git a/app_pojavlauncher/src/main/res/values-cs/strings.xml b/app_pojavlauncher/src/main/res/values-cs/strings.xml index e19b6d8063..62ba5299d2 100644 --- a/app_pojavlauncher/src/main/res/values-cs/strings.xml +++ b/app_pojavlauncher/src/main/res/values-cs/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ Vyberte instalátor módů - Amethyst neočekávaně spadl + Copper neočekávaně spadl Žádná verze! Zobrazit více Zobrazit méně @@ -210,7 +210,7 @@ Kápě Cosmetica Zapne kápě z Cosmeticy (dříve Arc) Pro více informací navštivte https://cosmetica.cc. Vyžaduje OptiFine. Všeobecné - Amethyst služba na popředí + Copper služba na popředí Nainstalováno (Užít globální výchozí nastavení) Výchozí ovládání @@ -408,7 +408,7 @@ Může pomoci s chybami shaderpacků. Zakažte, pokud to není třeba, může samo způsobovat pády. Použít výpočty mnohonásobnou emulace Používá výpočty stínů pro mnohonásobnou emulaci - Amethyst + Copper Na demo účtech jsou podporovány pouze Vanilla verze 1.3.1 a výše Demo profil není podporován Pro použití této funkce prosím změňte účty diff --git a/app_pojavlauncher/src/main/res/values-de/strings.xml b/app_pojavlauncher/src/main/res/values-de/strings.xml index 0a2a4d0b08..af06131526 100644 --- a/app_pojavlauncher/src/main/res/values-de/strings.xml +++ b/app_pojavlauncher/src/main/res/values-de/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ Wähle einen Mod-Installer - Amethyst ist unerwartet abgestürzt + Copper ist unerwartet abgestürzt Keine Version! Mehr anzeigen Weniger anzeigen @@ -210,7 +210,7 @@ Cosmetica-Umhänge Aktiviert Umhänge von Cosmetica (früher Arc). Für weitere Informationen, siehe https://cosmetica.cc. OptiFine wird benötigt. Allgemein - Amethyst-Vordergrunddienst + Copper-Vordergrunddienst Installiert (Standardvorgaben verwenden) Standard-Steuerung @@ -402,7 +402,7 @@ Um die offizielle Download-Quelle zu verwenden, drücke \"Auf offizielle Seite u Kann bei Shaderpack-Problemen helfen. Deaktivieren, wenn nicht benötigt, kann Abstürze verursachen. Nutze die Compute Multidraw-Emulation Verwendet den Compute-Shader Shader für die Multidraw-Emulation - Amethyst + Copper Auf Demo-Konten wird nur Vanilla 1.3.1 unterstützt Demo-Profil wird nicht unterstützt Bitte wechsle das Konto, um diese Funktion zu nutzen diff --git a/app_pojavlauncher/src/main/res/values-el/strings.xml b/app_pojavlauncher/src/main/res/values-el/strings.xml index 5573639a08..cc200b7189 100644 --- a/app_pojavlauncher/src/main/res/values-el/strings.xml +++ b/app_pojavlauncher/src/main/res/values-el/strings.xml @@ -11,7 +11,7 @@ Επιλέξτε ένα πρόγραμμα εγκατάστασης mod - Ο Amethyst κατέρρευσε απροσδόκητα + Ο Copper κατέρρευσε απροσδόκητα Καμία έκδοση! Εμφάνιση περισσότερων Εμφάνιση λιγότερων @@ -180,7 +180,7 @@ Ενεργοποιεί κάπες από τη Cosmetica (προηγουμένως Arc). Για περισσότερες πληροφορίες, παρακαλώ επισκεφθείτε την ιστοσελίδα https://cosmetica.cc. Απαιτείται το OptiFine. Γενικά - Υπηρεσία Προσκήνιου Amethyst + Υπηρεσία Προσκήνιου Copper (Χρήση της γενικής προεπιλογής) Προεπιλεγμένος χάρτης ελέγχου %d εργασίες σε εξέλιξη diff --git a/app_pojavlauncher/src/main/res/values-es/strings.xml b/app_pojavlauncher/src/main/res/values-es/strings.xml index 9f457512c1..ddf313591d 100644 --- a/app_pojavlauncher/src/main/res/values-es/strings.xml +++ b/app_pojavlauncher/src/main/res/values-es/strings.xml @@ -12,7 +12,7 @@ Seleccione un instalador de modificaciones - Amethyst se ha detenido de forma inesperada + Copper se ha detenido de forma inesperada ¡No hay versiones! Mostrar más Mostrar menos @@ -197,7 +197,7 @@ Capas de Comestica Activa las capas de Cosmetica (anteriormente Arc). Para más información ve a esta página https://cosmetica.cc. Necesitas Optifine. General - Servicio de primer plano de Amethyst + Servicio de primer plano de Copper Instalada (Usar predeterminado global) Controles por defecto diff --git a/app_pojavlauncher/src/main/res/values-et-rEE/strings.xml b/app_pojavlauncher/src/main/res/values-et-rEE/strings.xml index 45b4963b42..ae3ba44250 100644 --- a/app_pojavlauncher/src/main/res/values-et-rEE/strings.xml +++ b/app_pojavlauncher/src/main/res/values-et-rEE/strings.xml @@ -111,7 +111,7 @@ Cosmetica keebid Lubab Cosmetica (endine Arc) keebid. Rohkema teabe saamiseks külasta https://cosmetica.cc. Nõuab OptiFine\'i. Üldine - Amethyst esiplaaniteenus + Copper esiplaaniteenus Sundsulge Mäng töötab! Loo diff --git a/app_pojavlauncher/src/main/res/values-fa-rIR/strings.xml b/app_pojavlauncher/src/main/res/values-fa-rIR/strings.xml index b86e8c39e8..c894c380ce 100644 --- a/app_pojavlauncher/src/main/res/values-fa-rIR/strings.xml +++ b/app_pojavlauncher/src/main/res/values-fa-rIR/strings.xml @@ -181,7 +181,7 @@ شنل های Cosmetica شنل های Cosmetica (قبلاً Arc) را فعال می کند. برای اطلاعات بیشتر لطفاً به https://cosmetica.cc مراجعه کنید. به OptiFine نیاز دارد. عمومی - سرویس پیش‌زمینه Amethyst + سرویس پیش‌زمینه Copper نصب شد (از پیش‌فرض استفاده کنید) %d وظیفه در حال انجام diff --git a/app_pojavlauncher/src/main/res/values-fil/strings.xml b/app_pojavlauncher/src/main/res/values-fil/strings.xml index 7e2c427bbf..ce22e6541f 100644 --- a/app_pojavlauncher/src/main/res/values-fil/strings.xml +++ b/app_pojavlauncher/src/main/res/values-fil/strings.xml @@ -11,7 +11,7 @@ Pumili ng mod installer - Ang Amethyst ay hindi inaasahang nag-crash + Ang Copper ay hindi inaasahang nag-crash Walang bersyon! Tignan ang error Magpakita ng kaunti @@ -131,7 +131,7 @@ Capes galing sa Cosmetica Pinapagana ang mga kapa mula sa Cosmetica (ang dating Arc). Para sa karagdagang impormasyon mangyaring bisitahin ang https://cosmetica.cc Kinagangailangan ng OptiFine. Pangkalahatan - Serbisyong Harapan ng Amethyst + Serbisyong Harapan ng Copper Naka-Install Nagda-download %s Mga tweaks sa Java diff --git a/app_pojavlauncher/src/main/res/values-fr/strings.xml b/app_pojavlauncher/src/main/res/values-fr/strings.xml index 844d7038e1..a1f7d3534c 100644 --- a/app_pojavlauncher/src/main/res/values-fr/strings.xml +++ b/app_pojavlauncher/src/main/res/values-fr/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ Sélectionnez un installateur de mods - Amethyst a cessé de fonctionner de façon inattendue + Copper a cessé de fonctionner de façon inattendue Aucune version ! Afficher plus Afficher moins @@ -204,7 +204,7 @@ Capes Cosmetica Active les capes Cosmetica. Pour plus d\'informations visitez https://cosmetica.cc. Nécessite OptiFine. Général - Service de premier plan de Amethyst + Service de premier plan de Copper Installés (Utiliser la valeur globale par défaut) Contrôles par défaut @@ -395,7 +395,7 @@ Peut aider pour des bugs de shaders. À désactiver si ce n\'est pas nécessaire, peut causer des plantages. Utiliser l\'émulation de calcul multidessin Utilise les nuanceurs de calcul pour l\'émulation multidessin - Amethyst + Copper Seules les versions Vanilla 1.3.1 et supérieures sont supportées sur les comptes de démo Profil de démo non pris en charge Veuillez changer de compte pour utiliser cette fonction diff --git a/app_pojavlauncher/src/main/res/values-hu/strings.xml b/app_pojavlauncher/src/main/res/values-hu/strings.xml index e00a3e9030..e64b20eea2 100644 --- a/app_pojavlauncher/src/main/res/values-hu/strings.xml +++ b/app_pojavlauncher/src/main/res/values-hu/strings.xml @@ -14,7 +14,7 @@ Válassz ki egy mod telepítőt - A Amethyst váratlanul kicrashelt + A Copper váratlanul kicrashelt Nincs verzió! Mutass többet Mutass kevesebbet diff --git a/app_pojavlauncher/src/main/res/values-in/strings.xml b/app_pojavlauncher/src/main/res/values-in/strings.xml index b48087ead7..1619d0ca0d 100644 --- a/app_pojavlauncher/src/main/res/values-in/strings.xml +++ b/app_pojavlauncher/src/main/res/values-in/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ Pilih sebuah instaler mod - Amethyst tiba-tiba crash tanpa diduga + Copper tiba-tiba crash tanpa diduga Tidak ada versi yang terdeteksi! Selengkapnya Tampilkan Sedikit @@ -210,7 +210,7 @@ Capes Cosmetica Mengaktifkan capes dari Cosmetica (sebelumnya Arc). Untuk informasi lebih lanjut silahkan kunjungi https://cosmetica.cc. Membutuhkan OptiFine. Umum - Amethyst Sedang Berjalan Di Latar Depan + Copper Sedang Berjalan Di Latar Depan Terpasang (Gunakan global bawaan) Kontrol bawaan @@ -408,7 +408,7 @@ Mungkin membantu mengatasi glitch pada shaderpack. Nonaktifkan jika tidak diperlukan, karena bisa menyebabkan crash. Gunakan Emulasi Multidraw Compute Menggunakan compute shaders untuk emulasi multidraw - Amethyst + Copper Hanya Minecraft Vanilla versi 1.3.1 ke atas yang didukung untuk akun demo Profil Demo tidak di dukung Ganti akun terlebih dahulu untuk menggunakan fitur ini diff --git a/app_pojavlauncher/src/main/res/values-it/strings.xml b/app_pojavlauncher/src/main/res/values-it/strings.xml index 3156a08950..a7d96aac81 100644 --- a/app_pojavlauncher/src/main/res/values-it/strings.xml +++ b/app_pojavlauncher/src/main/res/values-it/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ Seleziona un installer mod - Amethyst è crashato inaspettatamente + Copper è crashato inaspettatamente Nessuna versione! Mostra altro Mostra meno @@ -207,7 +207,7 @@ Mantelli Cosmetica Abilità i mantelli di Cosmetica (precedentemente Arc). Per ulteriori informazioni visita https://cosmetica.cc. Necessita OptiFine. Generale - Servizio di Foreground Amethyst + Servizio di Foreground Copper Installato (Utilizza il predefinito globale) Controlli default @@ -400,7 +400,7 @@ se vuoi scaricare dalla sorgente ufficiale premi \"Passa al sito ufficiale"\ e r Può aiutare con glich dei shaderpack. Disabilitare se non necessario, può causare crash. Utilizza Calcola Emulazione Multidraw Usa i compute shaders per l\'emulazione multidraw - Amethyst + Copper Solo Vanilla 1.3.1 e superiori sono supportati su account demo Profilo demo non supportato Si prega di cambiare account per utilizzare questa funzione diff --git a/app_pojavlauncher/src/main/res/values-iw/strings.xml b/app_pojavlauncher/src/main/res/values-iw/strings.xml index 22ae2f4ed8..9f0e6ba681 100644 --- a/app_pojavlauncher/src/main/res/values-iw/strings.xml +++ b/app_pojavlauncher/src/main/res/values-iw/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ בחר מתקין mod - Amethyst קרס באופן בלתי צפוי + Copper קרס באופן בלתי צפוי אין גרסה! הצג עוד הצג פחות @@ -201,7 +201,7 @@ רינדור מאפשר שכמיות מאת Cosmetica (לשעבר Arc). לקבלת מידע נוסף, בקרו ב- https://cosmetica.cc. דורש OptiFine. כללי - שירות הרקע של Amethyst + שירות הרקע של Copper מותקן (השתמש בהגדרות ברירת המחדל הגלובליות) מפת בקר ברירת מחדל @@ -382,7 +382,7 @@ עשוי לעזור עם תקלות ב-shaderpack. השבת אם אין צורך בכך, עלול לגרום לקריסות. פרסם את הרחבת Shader החישוב הניסיונית עשוי לעזור עם תקלות ב-shaderpack. השבת אם אין צורך בכך, עלול לגרום לקריסות. - Amethyst + Copper רק Vanilla 1.3.1 ומעלה נתמכים בחשבונות דמו. פרופיל demo אינו נתמך בבקשה תשנה או תשני חשבונות כדי להשתמש באפשרות זו diff --git a/app_pojavlauncher/src/main/res/values-ja/strings.xml b/app_pojavlauncher/src/main/res/values-ja/strings.xml index 94ebb198e0..11303848a6 100644 --- a/app_pojavlauncher/src/main/res/values-ja/strings.xml +++ b/app_pojavlauncher/src/main/res/values-ja/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -13,7 +13,7 @@ Mod インストーラーを選択 - Amethyst が異常終了しました + Copper が異常終了しました バージョンがありません 詳細を表示 詳細を閉じる @@ -184,7 +184,7 @@ コスメチカ・ケープズ Cosmetica(以前のArc)のケープを有効にします。詳細については、https://cosmetica.ccをご覧ください。 OptiFineが必要です。 一般 - Amethyst フォアグラウンドサービス + Copper フォアグラウンドサービス インストール済み (グローバル既定値を使用する) %d タスクが進行中 @@ -282,5 +282,5 @@ 選択... コントロールの可視性 実験的なもの - Amethyst + Copper diff --git a/app_pojavlauncher/src/main/res/values-kk/strings.xml b/app_pojavlauncher/src/main/res/values-kk/strings.xml index d825773678..86959b4d96 100644 --- a/app_pojavlauncher/src/main/res/values-kk/strings.xml +++ b/app_pojavlauncher/src/main/res/values-kk/strings.xml @@ -11,7 +11,7 @@ Мод орнатқыш таңдау - Amethyst кенет іркілді + Copper кенет іркілді Нұсқа жоқ! Көрсету Жасыру diff --git a/app_pojavlauncher/src/main/res/values-ko/strings.xml b/app_pojavlauncher/src/main/res/values-ko/strings.xml index 740e478296..30e9801bc8 100644 --- a/app_pojavlauncher/src/main/res/values-ko/strings.xml +++ b/app_pojavlauncher/src/main/res/values-ko/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ 모드 설치기를 선택하세요 - Amethyst에 예기치 못한 충돌이 발생했어요 + Copper에 예기치 못한 충돌이 발생했어요 버전이 없습니다! 더 보기 간략히 보기 @@ -209,7 +209,7 @@ 더 많은 정보를 위해 https://cosmetica.cc 를 방문해주세요. 옵티파인이 필요합니다. 일반 - Amethyst 포그라운드 서비스 + Copper 포그라운드 서비스 설치됨 (글로벌 기본값 사용) 기본 조작 @@ -399,7 +399,7 @@ 쉐이더팩 버그 현상에 도움이 될 수 있습니다. 충돌을 유발할 수 있으므로 필요하지 않다면 비활성화하세요. Compute 기반 Multidraw 에뮬레이션 사용 Multidraw 에뮬레이션에 Compute 쉐이더를 사용합니다 - Amethyst + Copper 데모 계정에서는 바닐라 1.3.1 이상만 지원합니다 데모 프로필 지원 안함 이 기능을 사용하려면 계정을 변경하세요 diff --git a/app_pojavlauncher/src/main/res/values-la/strings.xml b/app_pojavlauncher/src/main/res/values-la/strings.xml index 3c52e41157..19fa22e440 100644 --- a/app_pojavlauncher/src/main/res/values-la/strings.xml +++ b/app_pojavlauncher/src/main/res/values-la/strings.xml @@ -9,7 +9,7 @@ Et ob hoc remotus! - Amethyst crashed subito + Copper crashed subito Chooz mod installr - Amethyst haz unexpectadly crashd + Copper haz unexpectadly crashd No vershun! Show mor Show les @@ -155,7 +155,7 @@ Java runtime Enablez capez from cosmetica (previously arc). For more informashun pleez visit https://cosmetica.cc. Requirez optifine. Geneal - Amethyst background police + Copper background police (Use Base Normal) %d taskz in progress Get rid of it diff --git a/app_pojavlauncher/src/main/res/values-lt/strings.xml b/app_pojavlauncher/src/main/res/values-lt/strings.xml index c6da586512..46e61d9c1a 100644 --- a/app_pojavlauncher/src/main/res/values-lt/strings.xml +++ b/app_pojavlauncher/src/main/res/values-lt/strings.xml @@ -12,7 +12,7 @@ Pasirinkite modifikacijų įdiegimui - Amethyst netikėtai išsijungė arba užlužo + Copper netikėtai išsijungė arba užlužo Nėra versijos! Rodyti daugiau Rodyti mažiau @@ -162,7 +162,7 @@ \"Cosmetica\" apvalkalai Įjungia apvalkalus iš \"Cosmetica\" (anksčiau \"Arc\"). Daugiau informacijos rasite https://cosmetica.cc. Reikalingas OptiFine. Pagrindinis - Amethyst foninis servisas + Copper foninis servisas Nutraukti Žaidimas bėga! Sukurti diff --git a/app_pojavlauncher/src/main/res/values-ms/strings.xml b/app_pojavlauncher/src/main/res/values-ms/strings.xml index 835fe7ccef..d6eed8c790 100644 --- a/app_pojavlauncher/src/main/res/values-ms/strings.xml +++ b/app_pojavlauncher/src/main/res/values-ms/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ Pilih sebuah pemasang mod - Amethyst telah ranap tanpa diduga + Copper telah ranap tanpa diduga Tiada versi! Tunjuk lebih banyak Tunjuk lebih sedikit @@ -210,7 +210,7 @@ Mantel Cosmetica Mendayakan mantel daripada Cosmetica (sebelum ini Arc). Untuk maklumat lanjut sila layari https://cosmetica.cc. Memerlukan OptiFine. Umum - Perkhidmatan Latar Depan Amethyst + Perkhidmatan Latar Depan Copper Dipasang (Gunakan lalai global) Peta kawalan lalai @@ -408,7 +408,7 @@ Boleh membantu dengan gangguan dengan pek pembayang. Nyahdayakan jika tidak diperlukan, boleh menyebabkan ranap. Gunakan Emulasi Compute Multidraw Menggunakan pembayang compute untuk emulasi multidraw - Amethyst + Copper Hanya versi 1.3.1 Vanila dan ke atas disokong pada akaun demo Profil Demo tidak disokong Sila tukar akaun untuk menggunakan fungsi ini diff --git a/app_pojavlauncher/src/main/res/values-nl/strings.xml b/app_pojavlauncher/src/main/res/values-nl/strings.xml index 55dc3d8061..985fea3369 100644 --- a/app_pojavlauncher/src/main/res/values-nl/strings.xml +++ b/app_pojavlauncher/src/main/res/values-nl/strings.xml @@ -11,7 +11,7 @@ Selecteer een mod installatie - Amethyst is onverwacht gecrasht + Copper is onverwacht gecrasht Geen versie! Meer weergeven Minder weergeven @@ -158,7 +158,7 @@ Verwijder Schakelt capes van Cosmetica in (voorheen Arc). Voor meer informatie ga naar https://cosmetica.cc. Vereist OptiFine. Algemeen - Amethyst voorgrond Service + Copper voorgrond Service (Gebruik globale standaardwaarde) Standaard controlmap %d taken in uitvoering diff --git a/app_pojavlauncher/src/main/res/values-no/strings.xml b/app_pojavlauncher/src/main/res/values-no/strings.xml index b8cdcf6928..efddec9744 100644 --- a/app_pojavlauncher/src/main/res/values-no/strings.xml +++ b/app_pojavlauncher/src/main/res/values-no/strings.xml @@ -11,7 +11,7 @@ Velg en mod installasjonprogram - Amethyst har uventet krasjet + Copper har uventet krasjet Ingen versjon! Vis mer Vis mindre diff --git a/app_pojavlauncher/src/main/res/values-pl/strings.xml b/app_pojavlauncher/src/main/res/values-pl/strings.xml index eaaaef64f9..f39ec50a02 100644 --- a/app_pojavlauncher/src/main/res/values-pl/strings.xml +++ b/app_pojavlauncher/src/main/res/values-pl/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ Wybierz instalator modyfikacji - Amethyst uległ nieoczekiwanej awarii + Copper uległ nieoczekiwanej awarii Brak wersji! Pokaż więcej Pokaż mniej @@ -212,7 +212,7 @@ Peleryny Cosmetica Włącza peleryny z Cosmetica (wcześniej Arc). Więcej informacji znajdziesz na stronie https://cosmetica.cc. Wymaga OptiFine. Ogólne - Usługa Amethyst Foreground + Usługa Copper Foreground Zainstalowane (Użyj ustawień globalnych) Domyślne sterowanie @@ -410,7 +410,7 @@ Może pomóc w przypadku problemów z shaderpackami. Jeśli nie jest potrzebne, wyłącz je, ponieważ może powodować awarie. Użyj emulacji obliczeniowej Multidraw Wykorzystuje shadery obliczeniowe do emulacji Multidraw - Amethyst + Copper Na kontach demonstracyjnych obsługiwane są wyłącznie wersje Vanilla 1.3.1 i nowsze Profil demonstracyjny nie jest obsługiwany Aby skorzystać z tej funkcji, zmień konto diff --git a/app_pojavlauncher/src/main/res/values-pt-rBR/strings.xml b/app_pojavlauncher/src/main/res/values-pt-rBR/strings.xml index b1fdf706a7..b75ad8cf55 100644 --- a/app_pojavlauncher/src/main/res/values-pt-rBR/strings.xml +++ b/app_pojavlauncher/src/main/res/values-pt-rBR/strings.xml @@ -13,7 +13,7 @@ Selecione um instalador de mod - O Amethyst parou de funcionar inesperadamente + O Copper parou de funcionar inesperadamente Nenhuma versão! Mostrar mais Mostrar menos diff --git a/app_pojavlauncher/src/main/res/values-pt/strings.xml b/app_pojavlauncher/src/main/res/values-pt/strings.xml index 153f0b8566..ed49f964bc 100644 --- a/app_pojavlauncher/src/main/res/values-pt/strings.xml +++ b/app_pojavlauncher/src/main/res/values-pt/strings.xml @@ -11,7 +11,7 @@ Seleciona um Instalador de mods - O Amethyst falhou inesperadamente + O Copper falhou inesperadamente Não existem versões! Mostrar mais Mostrar menos diff --git a/app_pojavlauncher/src/main/res/values-ro/strings.xml b/app_pojavlauncher/src/main/res/values-ro/strings.xml index d0a58b7363..02e7fe5f15 100644 --- a/app_pojavlauncher/src/main/res/values-ro/strings.xml +++ b/app_pojavlauncher/src/main/res/values-ro/strings.xml @@ -11,7 +11,7 @@ Selectează un instalator de mod - Amethyst s-a oprit neașteptat + Copper s-a oprit neașteptat Fără versiune! Arată mai mult Arată mai puțin @@ -134,7 +134,7 @@ Randator Pelerine Cosmetica Activează pelerinele de la Cosmetica (anterior Arc). Pentru mai multe informații, vizitează https://cosmetica.cc. Necesită OptiFine. - Serviciu Amethyst prim-plan + Serviciu Copper prim-plan Instalat (Utilizare implicită globală) %d sarcini în curs diff --git a/app_pojavlauncher/src/main/res/values-rpr/strings.xml b/app_pojavlauncher/src/main/res/values-rpr/strings.xml index f227ad3b34..a54c544e12 100644 --- a/app_pojavlauncher/src/main/res/values-rpr/strings.xml +++ b/app_pojavlauncher/src/main/res/values-rpr/strings.xml @@ -11,7 +11,7 @@ Выберите установщикъ модификаціи - Amethyst былъ остановленъ въ результатѣ курьёза + Copper былъ остановленъ въ результатѣ курьёза Нѣтъ версій! Развернуть Свернуть diff --git a/app_pojavlauncher/src/main/res/values-ru/strings.xml b/app_pojavlauncher/src/main/res/values-ru/strings.xml index 729e942507..f473d402d3 100644 --- a/app_pojavlauncher/src/main/res/values-ru/strings.xml +++ b/app_pojavlauncher/src/main/res/values-ru/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ Выберите установщик мода - Amethyst был остановлен в результате сбоя + Copper был остановлен в результате сбоя Нет версий! Развернуть Свернуть @@ -207,7 +207,7 @@ Плащи Cosmetica Включает плащи от Cosmetica (ранее Arc). Для получения дополнительной информации посетите https://cosmetica.cc. Требуется OptiFine. Общее - Активная служба Amethyst + Активная служба Copper Установлено (Как везде) Раскладка управления @@ -405,7 +405,7 @@ Может помочь при сбоях набора шейдеров. Отключите, если не требуется, может привести к сбоям. Использовать вычислительную эмуляцию MultiDraw Использует вычислительные шейдеры для эмуляции MultiDraw - Amethyst + Copper Только ванильные версии от 1.3.1 поддерживается для демонстрационных учётных записей Демо-профиль не поддерживается Пожалуйста, измените учётную запись для использования этой функции diff --git a/app_pojavlauncher/src/main/res/values-sk-rSK/strings.xml b/app_pojavlauncher/src/main/res/values-sk-rSK/strings.xml index 5022e15203..556eae2ae6 100644 --- a/app_pojavlauncher/src/main/res/values-sk-rSK/strings.xml +++ b/app_pojavlauncher/src/main/res/values-sk-rSK/strings.xml @@ -11,7 +11,7 @@ Vybrať installer módu - Amethyst neočakávane spadol + Copper neočakávane spadol Žiadne verzie! Zobraziť viac Zobraziť menej diff --git a/app_pojavlauncher/src/main/res/values-sv/strings.xml b/app_pojavlauncher/src/main/res/values-sv/strings.xml index 4cc5acba3b..55e568c7cf 100644 --- a/app_pojavlauncher/src/main/res/values-sv/strings.xml +++ b/app_pojavlauncher/src/main/res/values-sv/strings.xml @@ -11,7 +11,7 @@ Välj ett mod installationsprogram - Amethyst har oväntat kraschat + Copper har oväntat kraschat Ingen version! Visa mer Visa mindre diff --git a/app_pojavlauncher/src/main/res/values-th/strings.xml b/app_pojavlauncher/src/main/res/values-th/strings.xml index e903830b17..e85340f417 100644 --- a/app_pojavlauncher/src/main/res/values-th/strings.xml +++ b/app_pojavlauncher/src/main/res/values-th/strings.xml @@ -11,7 +11,7 @@ เลือกตัวติดตั้งม็อด - Amethyst ได้ขัดข้องโดยไม่คาดคิด + Copper ได้ขัดข้องโดยไม่คาดคิด ไม่มีเวอร์ชัน! แสดงเพิ่มเติม แสดงน้อยลง diff --git a/app_pojavlauncher/src/main/res/values-tr/strings.xml b/app_pojavlauncher/src/main/res/values-tr/strings.xml index 2c88da0543..eb5a0bff84 100644 --- a/app_pojavlauncher/src/main/res/values-tr/strings.xml +++ b/app_pojavlauncher/src/main/res/values-tr/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ Bir mod yükleyicisi seç - Amethyst beklenmedik bir sebepten dolayı çöktü + Copper beklenmedik bir sebepten dolayı çöktü Sürüm yok! Daha fazla göster Daha az göster @@ -210,7 +210,7 @@ Cosmetica Pelerinleri Cosmetica\'nın (eskiden Arc olarak biliniyordu) Pelerinlerini etkinleştirir. Daha fazla bilgi için lütfen https://cosmetica.cc\'u ziyaret edin. OptiFine gerektirir. Genel - Amethyst Önplan Hizmeti + Copper Önplan Hizmeti Kuruldu (Genel varsayılanı kullan) Varsayılan kontroller @@ -408,7 +408,7 @@ Shader paketi bozulmalarına yardımcı olabilir. Ihtiyaç yoksa devre dışı bırakın, çökmelere sebep olabilir. Hesaplama ile Çoklu Çizim Taklidi Kullan Çoklu çizim emülasyonu için hesaplama shader’larını kullanır - Amethyst + Copper Sadece Vanilla 1.3.1 ve üzeri sürümler deneme hesaplarında desteklenmektedir Deneme Profili desteklenmemektedir Lütfen hesapları değiştirmek için bu fonksiyonu kullanınız diff --git a/app_pojavlauncher/src/main/res/values-tt/strings.xml b/app_pojavlauncher/src/main/res/values-tt/strings.xml index aeb622d0f1..9c0b1683e2 100644 --- a/app_pojavlauncher/src/main/res/values-tt/strings.xml +++ b/app_pojavlauncher/src/main/res/values-tt/strings.xml @@ -12,7 +12,7 @@ Мод утырткычын сайлагыз - Amethyst сафтан көтелмичә чыкты + Copper сафтан көтелмичә чыкты Версия юк! Күбрәк күрсәтү Әзрәк күрсәтү diff --git a/app_pojavlauncher/src/main/res/values-uk/strings.xml b/app_pojavlauncher/src/main/res/values-uk/strings.xml index 582b701c29..08db58fd9c 100644 --- a/app_pojavlauncher/src/main/res/values-uk/strings.xml +++ b/app_pojavlauncher/src/main/res/values-uk/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ Вибрати встановлювач мода - Amethyst був зупинений у результаті збою + Copper був зупинений у результаті збою Немає версії! Розвернути Звернути @@ -212,7 +212,7 @@ Плащі Cosmetica Умикає плащі від Cosmetica (раніше Arc). Для більш детальної інформації, будь ласка, відвідайте https://cosmetica.cc. Потребує OptiFine. Загальне - Служба Amethyst + Служба Copper Установлено (Використовувати усталено) Усталене керування @@ -410,7 +410,7 @@ Може допомогти у вирішенні збоїв у пакеті шейдерів. Вимкніть, якщо не потрібно, це може призвести до збоїв. Викор. емуляцію обчислення Multidraw Використовує обчислювальні шейдери для емуляції Multidraw - Amethyst + Copper Лише усталена версія 1.3.1 і вище підтримуються демо обліковим записом Демопрофіль не підтримується Будь ласка, змініть обліковий запис для використання функції diff --git a/app_pojavlauncher/src/main/res/values-vi/strings.xml b/app_pojavlauncher/src/main/res/values-vi/strings.xml index 2aa4bbc686..90e76cb307 100644 --- a/app_pojavlauncher/src/main/res/values-vi/strings.xml +++ b/app_pojavlauncher/src/main/res/values-vi/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ Chọn một trình cài đặt mod - Amethyst đã bị thoát đột ngột + Copper đã bị thoát đột ngột Không có phiên bản nào! Hiện thêm Thu gọn @@ -210,7 +210,7 @@ Áo choàng Cosmetica Sử dụng áo choàng từ Cosmetica (trước đây gọi là Arc). Để biết thêm thông tin, hãy truy cập https://cosmetica.cc. Yêu cầu sử dụng OptiFine. Chung - Dịch vụ tiền cảnh Amethyst + Dịch vụ tiền cảnh Copper Đã cài đặt (Sử dụng mặc định chung) Bố cục điều khiển mặc định @@ -408,7 +408,7 @@ Có thể giúp giảm hiện tượng lỗi trên các gói shader. Tính năng cũng có thể gây thoát đột ngột, hãy tắt nếu không cần thiết. Mô phỏng tính toán Multidraw Dùng shader tính toán để mô phỏng Multidraw - Amethyst + Copper Tài khoản chơi thử chỉ hỗ trợ chạy phiên bản từ 1.3.1 trở lên Không hỗ trợ chế độ chơi thử Vui lòng thay đổi tài khoản để sử dụng chức năng này diff --git a/app_pojavlauncher/src/main/res/values-zh-rCN/strings.xml b/app_pojavlauncher/src/main/res/values-zh-rCN/strings.xml index 5577d3f022..4c89b468f6 100644 --- a/app_pojavlauncher/src/main/res/values-zh-rCN/strings.xml +++ b/app_pojavlauncher/src/main/res/values-zh-rCN/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ 选择模组安装器 - Amethyst 意外崩溃 + Copper 意外崩溃 无可用版本! 显示详情 隐藏详情 @@ -213,7 +213,7 @@ Cosmetica 披风 启用来自 Cosmetica(原 Arc)的披风。欲了解更多信息,请访问 https://cosmetica.cc。需要 OptiFine。 通用 - Amethyst 前台服务 + Copper 前台服务 已安装 (使用全局默认设置) 默认控制键布局 @@ -417,7 +417,7 @@ 设置使用 TouchController 时的震动长度。 使用计算多重绘制模拟 使用计算着色器进行多重绘制模拟 - Amethyst + Copper 试玩账户仅支持原版 1.3.1 及以上版本 不支持试玩玩家档案 请更换账户以使用此功能 diff --git a/app_pojavlauncher/src/main/res/values-zh-rTW/strings.xml b/app_pojavlauncher/src/main/res/values-zh-rTW/strings.xml index 06bb146512..e63ee7d635 100644 --- a/app_pojavlauncher/src/main/res/values-zh-rTW/strings.xml +++ b/app_pojavlauncher/src/main/res/values-zh-rTW/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -14,7 +14,7 @@ 選擇模組安裝器 - Amethyst 意外崩潰 + Copper 意外崩潰 無可用版本! 顯示詳情 隱藏詳情 @@ -210,7 +210,7 @@ Cosmetica 披風 啟用來自 Cosmetica(原 Arc)的披風。欲瞭解更多資訊,請訪問 https://cosmetica.cc。需要 OptiFine。 一般 - Amethyst 前臺服務 + Copper 前臺服務 已安裝 (使用全域預設設定) 預設控制鍵位 @@ -409,7 +409,7 @@ 可能有助於解決光影渲染問題。不需要時請禁用,否則可能會導致崩潰。 使用計算多重繪制模擬 使用計算著色器進行多重繪制模擬 - Amethyst + Copper 試玩帳號僅支持原版 1.3.1 及以上版本 不支持試玩玩家檔案 請更換帳號以使用此功能 diff --git a/app_pojavlauncher/src/main/res/values/colors.xml b/app_pojavlauncher/src/main/res/values/colors.xml index 927d9694ef..11c78ffb0e 100644 --- a/app_pojavlauncher/src/main/res/values/colors.xml +++ b/app_pojavlauncher/src/main/res/values/colors.xml @@ -3,7 +3,7 @@ #4CC4C4C4 #4D000000 - #9649b8 + #FFA602 #181818 @color/background_overlay #464646 @@ -12,4 +12,4 @@ #FFFFFF #B2B2B2 - \ No newline at end of file + diff --git a/app_pojavlauncher/src/main/res/values/headings_array.xml b/app_pojavlauncher/src/main/res/values/headings_array.xml index f8f6f0f715..7f16be7b41 100644 --- a/app_pojavlauncher/src/main/res/values/headings_array.xml +++ b/app_pojavlauncher/src/main/res/values/headings_array.xml @@ -1,11 +1,11 @@ - @string/mcl_setting_renderer_ng_gl4es - @string/mcl_setting_renderer_vulkan_kopper_zink + @string/mcl_setting_renderer_gles2_4 @string/mcl_setting_renderer_vulkan_zink @string/mcl_setting_renderer_mobileglues @string/mcl_setting_renderer_ltw + @string/mcl_setting_renderer_KW @@ -37,11 +37,12 @@ - opengles2 - opengles3_desktopgl_zink_kopper - vulkan_zink + opengles2 + opengles3_desktopgl_zink opengles_mobileglues opengles3_ltw + opengles3_KW + @string/global_default diff --git a/app_pojavlauncher/src/main/res/values/strings.xml b/app_pojavlauncher/src/main/res/values/strings.xml index 6f695e916d..5196fcc379 100644 --- a/app_pojavlauncher/src/main/res/values/strings.xml +++ b/app_pojavlauncher/src/main/res/values/strings.xml @@ -1,7 +1,7 @@ - Amethyst + Copper @@ -21,7 +21,7 @@ Select a mod installer - Amethyst has unexpectedly crashed + Copper has unexpectedly crashed No version! Show more Show less @@ -66,10 +66,10 @@ Renderer specific settings Renderer Holy GL4ES - (1.21.4< only, fast) - Krypton Wrapper - (all versions, fast) Zink (Vulkan) - (all versions, mid) MobileGlues (OpenGL ES) - (1.17+ only, fast) LTW (OpenGL ES 3) - 1.17+ only + Krypton Wrapper - (all versions, fast) Release Snapshot Old-alpha @@ -92,6 +92,12 @@ Wait Select Retry + Back + Add + No mods installed for this profile. + Delete %s? + %s installed to mods folder. + Search for mods Default Off @@ -244,7 +250,7 @@ FFFF0000 General channel_id - Amethyst Foreground Service + Copper Foreground Service Installed (Use global default) Default controlmap @@ -335,6 +341,8 @@ No modpacks found Failed to find modpacks + No mods found + Failed to find mods Failed to download modpack metadata Downloading modpack metadata (%.2f MB / %.2f MB) @@ -427,9 +435,16 @@ Change controller key bindings Allows you to modify the keyboard keys bound to each controller button Discord + Quick Actions + Instance Tools + Mod Store + Settings + Manage Mods & Tools + Install Modpack (.mrpack/zip) + Delete Your GPU is not capable of rendering above 7 render distance without Sodium or other similar mods. The render distance will be automatically reduced when you click "OK". Open game directory - https://discord.gg/5ptqkyZxEy + https://discord.gg/8WzF2RVAq4 Unsuitable username The username must be between 3–16 characters long, and must only contain latin letters, numbers 0–9 and underscores. Quick settings @@ -458,7 +473,7 @@ May help with shaderpack glitches. Disable if not needed, can cause crashes. Use Compute Multidraw Emulation Uses compute shaders for multidraw emulation - Amethyst + Copper Only Vanilla 1.3.1 and above are supported on demo accounts Demo Profile not supported Please change accounts to use this function @@ -489,10 +504,9 @@ May help with Iris shaderpacks, required for AcceleratedRendering mod AMD FSR 1 Upscaling Auto-renderer select failed, defaulting to HolyGL4ES - Kopper Zink (Vulkan) - (all versions, mid) Sodium detected! It appears you are using sodium, this is unsupported and may lead to graphical issues or crashes. Please remove it and all dependent mods. - Delete Sodium and Launch + Delete Sodium and Launch report this if you see this it should have been removed Run sodium forcefully Using sodium may cause visual bugs and crashes. You have been warned. Sodium is not supported. No help will be given if you encounter any issues. @@ -507,4 +521,7 @@ Failed to download, check your internet connection. Installing… + Select dependencies to install + Install selected + Install without deps diff --git a/app_pojavlauncher/src/main/res/xml/pref_experimental.xml b/app_pojavlauncher/src/main/res/xml/pref_experimental.xml index c3536d559c..59443c39c6 100644 --- a/app_pojavlauncher/src/main/res/xml/pref_experimental.xml +++ b/app_pojavlauncher/src/main/res/xml/pref_experimental.xml @@ -14,12 +14,5 @@ android:key="bigCoreAffinity" android:title="@string/preference_force_big_core_title" android:summary="@string/preference_force_big_core_desc" /> - - - \ No newline at end of file + diff --git a/app_pojavlauncher/src/main/res/xml/pref_renderer.xml b/app_pojavlauncher/src/main/res/xml/pref_renderer.xml index a8de311bef..45baceaf95 100644 --- a/app_pojavlauncher/src/main/res/xml/pref_renderer.xml +++ b/app_pojavlauncher/src/main/res/xml/pref_renderer.xml @@ -51,6 +51,11 @@ android:defaultValue="false" /> + diff --git a/jre_lwjgl3glfw/lwjgl-3.3.3/src/main/java/org/lwjgl/opengl/PojavRendererInit.java b/jre_lwjgl3glfw/lwjgl-3.3.3/src/main/java/org/lwjgl/opengl/PojavRendererInit.java index 4670d854b5..70b358d537 100644 --- a/jre_lwjgl3glfw/lwjgl-3.3.3/src/main/java/org/lwjgl/opengl/PojavRendererInit.java +++ b/jre_lwjgl3glfw/lwjgl-3.3.3/src/main/java/org/lwjgl/opengl/PojavRendererInit.java @@ -26,7 +26,7 @@ public static void onCreateCapabilities(FunctionProvider functionProvider) { "Renderer-specific initialization may not work properly"); } // NOTE: hardcoded gl4es libname - if(rendererName.endsWith("libng_gl4es.so")) { + if(rendererName.endsWith("libgl4es_115.so")) { nativeInitGl4esInternals(functionProvider); } } diff --git a/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/lwjgl2_methods_injector/ALC10Injector.java b/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/lwjgl2_methods_injector/ALC10Injector.java index 355885afcc..c9a04ea7ea 100644 --- a/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/lwjgl2_methods_injector/ALC10Injector.java +++ b/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/lwjgl2_methods_injector/ALC10Injector.java @@ -30,7 +30,7 @@ public byte[] transform(ClassLoader l, String name, Class c, return null; } try { // Minecraft makes it ugly if we use println - System.out.write("Amethyst-Android: Adding missing LWJGL2 methods for better sound mod compatibility...\n".getBytes()); + System.out.write("Copper-Android: Adding missing LWJGL2 methods for better sound mod compatibility...\n".getBytes()); System.out.flush(); } catch (Exception ignored) {} ClassReader cr = new ClassReader(b); diff --git a/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/lwjgl2_methods_injector/ASM5OverrideInjector.java b/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/lwjgl2_methods_injector/ASM5OverrideInjector.java index b682a11545..bd6524ed48 100644 --- a/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/lwjgl2_methods_injector/ASM5OverrideInjector.java +++ b/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/lwjgl2_methods_injector/ASM5OverrideInjector.java @@ -28,7 +28,7 @@ public byte[] transform(ClassLoader l, String name, Class c, ProtectionDomain d, name.endsWith("AnnotationVisitor") || name.endsWith("SignatureVisitor")) { try { // Minecraft makes it ugly if we use println - System.out.print("Amethyst-Android: Modifying ASM classes for ASM4 comaptibility...\n"); + System.out.print("Copper-Android: Modifying ASM classes for ASM4 comaptibility...\n"); } catch (Exception ignored) {} ClassReader cr = new ClassReader(b); ClassWriter cw = new ClassWriter(cr, 0); diff --git a/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/mod_compatibility_injector/VeilImguiOverrideDisable.java b/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/mod_compatibility_injector/VeilImguiOverrideDisable.java index 8d3458dba0..c83ed57fa4 100644 --- a/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/mod_compatibility_injector/VeilImguiOverrideDisable.java +++ b/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/mod_compatibility_injector/VeilImguiOverrideDisable.java @@ -46,10 +46,10 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si if (name.equals("setImGuiPath") && desc.equals("()V")) { try { // Minecraft makes it ugly if we use println - System.out.write(("Amethyst-Android: Patching VeilImGuiImpl for faulty setImGuiPath()...\n" + + System.out.write(("Copper-Android: Patching VeilImGuiImpl for faulty setImGuiPath()...\n" + "This issue is fixed in Veil 3.1.1 and above. See https://github.com/FoundryMC/Veil/commit/8e0e09365049a106bfa3634e2ed78a0310c5b4df\n" + - "The intended target of this patch is Veil 3.1.0 and below. If you see this log output without Veil 3.1.0 or lower running, please send a bug report to Amethyst-Android.\n" + - "https://github.com/AngelAuraMC/Amethyst-Android/issues/new?template=bug_report.yml").getBytes()); + "The intended target of this patch is Veil 3.1.0 and below. If you see this log output without Veil 3.1.0 or lower running, please send a bug report to Copper-Android.\n" + + "https://github.com/AngelAuraMC/Copper-Android/issues/new?template=bug_report.yml").getBytes()); System.out.flush(); } catch (Exception ignored) {} diff --git a/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/startInjectors.java b/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/startInjectors.java index 83ba3502d2..bdf44240b8 100644 --- a/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/startInjectors.java +++ b/methods_injector_agent/src/main/java/org/angelauramc/methodsInjectorAgent/startInjectors.java @@ -18,7 +18,7 @@ public static void premain(String args, Instrumentation inst) { Package asmPackage = org.objectweb.asm.Opcodes.class.getPackage(); String implVersion = asmPackage.getImplementationVersion(); if (implVersion == null) implVersion = "not found"; - System.out.println("Amethyst-Android: Detected ASM version: " + implVersion); + System.out.println("Copper-Android: Detected ASM version: " + implVersion); ALC10Injector.premain(args, inst); VeilImguiOverrideDisable.premain(args, inst); // This is the version we override old asm vers with. So we add the patches diff --git a/settings.gradle b/settings.gradle index 4576009968..623e25c004 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,7 +14,7 @@ dependencyResolutionManagement { } } -rootProject.name='Amethyst' +rootProject.name='Copper' include ':jre_lwjgl3glfw' include ":jre_lwjgl3glfw:lwjgl-3.3.3" include ":jre_lwjgl3glfw:lwjgl-3.4.1"