From 58d1625672f1934e1660b334c4bb0503e0db644b Mon Sep 17 00:00:00 2001 From: SSimco <37044560+SSimco@users.noreply.github.com> Date: Sat, 16 Aug 2025 17:27:42 +0300 Subject: [PATCH] Fix graphic packs download error --- src/android/app/build.gradle.kts | 1 - .../graphicpacks/GraphicPacksDownloader.kt | 64 +++++++++++++------ .../graphicpacks/GraphicPacksListViewModel.kt | 6 +- ...cPacksScreen.kt => GraphicPacksScreens.kt} | 11 ++-- .../src/main/java/info/cemu/cemu/utils/Zip.kt | 8 ++- 5 files changed, 60 insertions(+), 30 deletions(-) rename src/android/app/src/main/java/info/cemu/cemu/graphicpacks/{GraphicPacksScreen.kt => GraphicPacksScreens.kt} (96%) diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts index 8c83dd18..c1de952d 100644 --- a/src/android/app/build.gradle.kts +++ b/src/android/app/build.gradle.kts @@ -231,7 +231,6 @@ dependencies { implementation(libs.androidx.ui.graphics) implementation(libs.androidx.compose.material3) testImplementation(libs.junit) - testImplementation(libs.kotlin.reflect) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) androidTestImplementation(platform(libs.androidx.compose.bom)) diff --git a/src/android/app/src/main/java/info/cemu/cemu/graphicpacks/GraphicPacksDownloader.kt b/src/android/app/src/main/java/info/cemu/cemu/graphicpacks/GraphicPacksDownloader.kt index d4659646..d77bd619 100644 --- a/src/android/app/src/main/java/info/cemu/cemu/graphicpacks/GraphicPacksDownloader.kt +++ b/src/android/app/src/main/java/info/cemu/cemu/graphicpacks/GraphicPacksDownloader.kt @@ -1,6 +1,7 @@ package info.cemu.cemu.graphicpacks import android.content.Context +import info.cemu.cemu.BuildConfig import info.cemu.cemu.nativeinterface.NativeGraphicPacks import info.cemu.cemu.utils.unzip import kotlinx.coroutines.Dispatchers @@ -14,13 +15,14 @@ import java.io.IOException import kotlin.io.path.div import kotlin.io.path.readText -sealed class GraphicPacksDownloadStatus { - data object CheckingForUpdates : GraphicPacksDownloadStatus() - data object NoUpdatesAvailable : GraphicPacksDownloadStatus() - data object Downloading : GraphicPacksDownloadStatus() - data object FinishedDownloading : GraphicPacksDownloadStatus() - data object Error : GraphicPacksDownloadStatus() - data object Canceled : GraphicPacksDownloadStatus() +enum class GraphicPacksDownloadStatus { + CHECKING_VERSION, + NO_UPDATES_AVAILABLE, + DOWNLOADING, + EXTRACTING, + FINISHED_DOWNLOADING, + ERROR, + CANCELED } class GraphicPacksDownloader { @@ -29,7 +31,7 @@ class GraphicPacksDownloader { graphicPacksDir.toPath() / "downloadedGraphicPacks" / "version.txt" return try { graphicPacksVersionFile.readText() - } catch (ignored: IOException) { + } catch (_: IOException) { null } } @@ -40,31 +42,53 @@ class GraphicPacksDownloader { ) { val graphicPacksRootDir = context.getExternalFilesDir(null) if (graphicPacksRootDir == null) { - updateStatus(GraphicPacksDownloadStatus.Error) + updateStatus(GraphicPacksDownloadStatus.ERROR) return } + val graphicPacksDirPath = graphicPacksRootDir.toPath() / "graphicPacks" checkForNewUpdate(graphicPacksDirPath.toFile(), updateStatus) } + private suspend fun getUpdateUrl(): String { + val queryUrl = "https://cemu.info/api2/query_graphicpack_url.php?" + + "version=${BuildConfig.VERSION_NAME}" + + "&t=${System.currentTimeMillis()}" + + val request = Request.Builder() + .url(queryUrl) + .build() + + Client.newCall(request).executeAsync().use { response -> + if (response.isSuccessful) { + val body = response.body.string().trim() + if (body.startsWith("http")) { + return body + } + } + } + + return "https://api.github.com/repos/cemu-project/cemu_graphic_packs/releases/latest" + } + private suspend fun checkForNewUpdate( graphicPacksDir: File, updateStatus: suspend (GraphicPacksDownloadStatus) -> Unit ) { - updateStatus(GraphicPacksDownloadStatus.CheckingForUpdates) + updateStatus(GraphicPacksDownloadStatus.CHECKING_VERSION) val request = Request.Builder() - .url(GITHUB_RELEASES_API_URL) + .url(getUpdateUrl()) .build() Client.newCall(request).executeAsync().use { response -> withContext(Dispatchers.IO) { if (!response.isSuccessful) { - updateStatus(GraphicPacksDownloadStatus.Error) + updateStatus(GraphicPacksDownloadStatus.ERROR) return@withContext } val json = JSONObject(response.body.string()) val version = json.getString("name") if (getCurrentVersion(graphicPacksDir) == version) { - updateStatus(GraphicPacksDownloadStatus.NoUpdatesAvailable) + updateStatus(GraphicPacksDownloadStatus.NO_UPDATES_AVAILABLE) return@withContext } val downloadUrl = json.getJSONArray("assets") @@ -81,16 +105,21 @@ class GraphicPacksDownloader { version: String, updateStatus: suspend (GraphicPacksDownloadStatus) -> Unit ) { - updateStatus(GraphicPacksDownloadStatus.Downloading) + updateStatus(GraphicPacksDownloadStatus.DOWNLOADING) + val request = Request.Builder() .url(downloadUrl) .build() + Client.newCall(request).executeAsync().use { response -> withContext(Dispatchers.IO) { if (!response.isSuccessful) { - updateStatus(GraphicPacksDownloadStatus.Error) + updateStatus(GraphicPacksDownloadStatus.ERROR) return@withContext } + + updateStatus(GraphicPacksDownloadStatus.EXTRACTING) + val graphicPacksTempDir = graphicPacksDir.resolve("downloadedGraphicPacksTemp") graphicPacksTempDir.deleteRecursively() unzip( @@ -103,14 +132,13 @@ class GraphicPacksDownloader { downloadedGraphicPacksDir.deleteRecursively() graphicPacksTempDir.renameTo(downloadedGraphicPacksDir) NativeGraphicPacks.refreshGraphicPacks() - updateStatus(GraphicPacksDownloadStatus.FinishedDownloading) + + updateStatus(GraphicPacksDownloadStatus.FINISHED_DOWNLOADING) } } } companion object { private val Client = OkHttpClient() - private const val GITHUB_RELEASES_API_URL = - "https://api.github.com/repos/cemu-project/cemu_graphic_packs/releases/latest" } } \ No newline at end of file diff --git a/src/android/app/src/main/java/info/cemu/cemu/graphicpacks/GraphicPacksListViewModel.kt b/src/android/app/src/main/java/info/cemu/cemu/graphicpacks/GraphicPacksListViewModel.kt index 3e003c6d..c46d74f5 100644 --- a/src/android/app/src/main/java/info/cemu/cemu/graphicpacks/GraphicPacksListViewModel.kt +++ b/src/android/app/src/main/java/info/cemu/cemu/graphicpacks/GraphicPacksListViewModel.kt @@ -22,7 +22,7 @@ class GraphicPacksListViewModel : ViewModel() { private val installedTitleIds = NativeGameTitles.getInstalledGamesTitleIds() private var rootNode = GraphicPackSectionNode() - private val _installedOnly = MutableStateFlow(true) + private val _installedOnly = MutableStateFlow(installedTitleIds.size > 1) val installedOnly = _installedOnly.asStateFlow() fun setInstalledOnly(installedOnly: Boolean) { _installedOnly.value = installedOnly @@ -45,7 +45,7 @@ class GraphicPacksListViewModel : ViewModel() { GraphicPacksDownloader.download(context) { updateDownloadStatus(it) } refreshGraphicPacks() } catch (exception: Exception) { - updateDownloadStatus(GraphicPacksDownloadStatus.Error) + updateDownloadStatus(GraphicPacksDownloadStatus.ERROR) } } } @@ -58,7 +58,7 @@ class GraphicPacksListViewModel : ViewModel() { downloadJob?.cancel(CancellationException("Canceled by user")) downloadJob = null viewModelScope.launch { - updateDownloadStatus(GraphicPacksDownloadStatus.Canceled) + updateDownloadStatus(GraphicPacksDownloadStatus.CANCELED) } } diff --git a/src/android/app/src/main/java/info/cemu/cemu/graphicpacks/GraphicPacksScreen.kt b/src/android/app/src/main/java/info/cemu/cemu/graphicpacks/GraphicPacksScreens.kt similarity index 96% rename from src/android/app/src/main/java/info/cemu/cemu/graphicpacks/GraphicPacksScreen.kt rename to src/android/app/src/main/java/info/cemu/cemu/graphicpacks/GraphicPacksScreens.kt index a42f2b20..382eff78 100644 --- a/src/android/app/src/main/java/info/cemu/cemu/graphicpacks/GraphicPacksScreen.kt +++ b/src/android/app/src/main/java/info/cemu/cemu/graphicpacks/GraphicPacksScreens.kt @@ -158,16 +158,17 @@ fun GraphicPacksRootSectionScreen( private fun downloadStatusToDialogTextString(downloadStatus: GraphicPacksDownloadStatus?): String? = when (downloadStatus) { - GraphicPacksDownloadStatus.CheckingForUpdates -> tr("Checking version") - GraphicPacksDownloadStatus.Downloading -> tr("Downloading graphic packs") + GraphicPacksDownloadStatus.CHECKING_VERSION -> tr("Checking version...") + GraphicPacksDownloadStatus.DOWNLOADING -> tr("Downloading graphic packs...") + GraphicPacksDownloadStatus.EXTRACTING -> tr("Extracting...") else -> null } private fun downloadStatusToNotificationString(downloadStatus: GraphicPacksDownloadStatus?): String? = when (downloadStatus) { - GraphicPacksDownloadStatus.Error -> tr("Failed to download graphic packs") - GraphicPacksDownloadStatus.FinishedDownloading -> tr("Downloaded latest graphic packs") - GraphicPacksDownloadStatus.NoUpdatesAvailable -> tr("No updates available") + GraphicPacksDownloadStatus.ERROR -> tr("Failed to download graphic packs") + GraphicPacksDownloadStatus.FINISHED_DOWNLOADING -> tr("Downloaded latest graphic packs") + GraphicPacksDownloadStatus.NO_UPDATES_AVAILABLE -> tr("No updates available.") else -> null } diff --git a/src/android/app/src/main/java/info/cemu/cemu/utils/Zip.kt b/src/android/app/src/main/java/info/cemu/cemu/utils/Zip.kt index 0d9cdf95..2916bbef 100644 --- a/src/android/app/src/main/java/info/cemu/cemu/utils/Zip.kt +++ b/src/android/app/src/main/java/info/cemu/cemu/utils/Zip.kt @@ -9,11 +9,13 @@ import java.util.zip.ZipInputStream fun unzip(stream: InputStream, targetDir: String) { ZipInputStream(stream).use { zipInputStream -> - var zipEntry: ZipEntry val buffer = ByteArray(8192) - while ((zipInputStream.nextEntry.also { zipEntry = it }) != null) { + + var zipEntry: ZipEntry? = zipInputStream.nextEntry + + while (zipEntry != null) { extractZipEntry(zipInputStream, zipEntry, buffer, targetDir) - zipInputStream.closeEntry() + zipEntry = zipInputStream.nextEntry } } }