mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-02-04 02:51:18 +01:00
[cmake, frontend] Add nightly build modifier (#3431)
The `NIGHTLY_BUILD` option changes the app name to "Eden Nightly" and changes the auto-update URL to use our new Nightly repository. This needs added to Android, but I can't right now as I have to leave. Signed-off-by: crueter <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3431
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
NUM_JOBS=$(nproc 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || echo 2)
|
NUM_JOBS=$(nproc 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || echo 2)
|
||||||
@@ -29,6 +29,7 @@ Options:
|
|||||||
-b, --build-type <TYPE> Build type (variable: TYPE)
|
-b, --build-type <TYPE> Build type (variable: TYPE)
|
||||||
Valid values are: Release, RelWithDebInfo, Debug
|
Valid values are: Release, RelWithDebInfo, Debug
|
||||||
Default: Debug
|
Default: Debug
|
||||||
|
-n, --nightly Create a nightly build.
|
||||||
|
|
||||||
Extra arguments are passed to CMake (e.g. -DCMAKE_OPTION_NAME=VALUE)
|
Extra arguments are passed to CMake (e.g. -DCMAKE_OPTION_NAME=VALUE)
|
||||||
Set the CCACHE variable to "true" to enable build caching.
|
Set the CCACHE variable to "true" to enable build caching.
|
||||||
@@ -61,6 +62,7 @@ while true; do
|
|||||||
-r|--release) DEVEL=false ;;
|
-r|--release) DEVEL=false ;;
|
||||||
-t|--target) target "$2"; shift ;;
|
-t|--target) target "$2"; shift ;;
|
||||||
-b|--build-type) type "$2"; shift ;;
|
-b|--build-type) type "$2"; shift ;;
|
||||||
|
-n|--nightly) NIGHTLY=true ;;
|
||||||
-h|--help) usage ;;
|
-h|--help) usage ;;
|
||||||
*) break ;;
|
*) break ;;
|
||||||
esac
|
esac
|
||||||
@@ -101,7 +103,20 @@ cd src/android
|
|||||||
chmod +x ./gradlew
|
chmod +x ./gradlew
|
||||||
|
|
||||||
set -- "$@" -DUSE_CCACHE="${CCACHE}"
|
set -- "$@" -DUSE_CCACHE="${CCACHE}"
|
||||||
[ "$DEVEL" != "true" ] && set -- "$@" -DENABLE_UPDATE_CHECKER=ON
|
|
||||||
|
nightly() {
|
||||||
|
[ "$NIGHTLY" = "true" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
if nightly || [ "$DEVEL" != "true" ]; then
|
||||||
|
set -- "$@" -DENABLE_UPDATE_CHECKER=ON
|
||||||
|
fi
|
||||||
|
|
||||||
|
if nightly; then
|
||||||
|
NIGHTLY=true
|
||||||
|
else
|
||||||
|
NIGHTLY=false
|
||||||
|
fi
|
||||||
|
|
||||||
echo "-- building..."
|
echo "-- building..."
|
||||||
|
|
||||||
@@ -110,6 +125,7 @@ echo "-- building..."
|
|||||||
-Dorg.gradle.parallel="${CCACHE}" \
|
-Dorg.gradle.parallel="${CCACHE}" \
|
||||||
-Dorg.gradle.workers.max="${NUM_JOBS}" \
|
-Dorg.gradle.workers.max="${NUM_JOBS}" \
|
||||||
-PYUZU_ANDROID_ARGS="$*" \
|
-PYUZU_ANDROID_ARGS="$*" \
|
||||||
|
-Pnightly="$NIGHTLY" \
|
||||||
--info
|
--info
|
||||||
|
|
||||||
if [ -n "${ANDROID_KEYSTORE_B64}" ]; then
|
if [ -n "${ANDROID_KEYSTORE_B64}" ]; then
|
||||||
|
|||||||
@@ -227,6 +227,8 @@ option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android"
|
|||||||
|
|
||||||
option(YUZU_LEGACY "Apply patches that improve compatibility with older GPUs (e.g. Snapdragon 865) at the cost of performance" OFF)
|
option(YUZU_LEGACY "Apply patches that improve compatibility with older GPUs (e.g. Snapdragon 865) at the cost of performance" OFF)
|
||||||
|
|
||||||
|
option(NIGHTLY_BUILD "Use Nightly qualifiers in the update checker and build metadata" OFF)
|
||||||
|
|
||||||
cmake_dependent_option(YUZU_ROOM "Enable dedicated room functionality" ON "NOT ANDROID" OFF)
|
cmake_dependent_option(YUZU_ROOM "Enable dedicated room functionality" ON "NOT ANDROID" OFF)
|
||||||
cmake_dependent_option(YUZU_ROOM_STANDALONE "Enable standalone room executable" ON "YUZU_ROOM" OFF)
|
cmake_dependent_option(YUZU_ROOM_STANDALONE "Enable standalone room executable" ON "YUZU_ROOM" OFF)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
# SPDX-FileCopyrightText: 2019 yuzu Emulator Project
|
# SPDX-FileCopyrightText: 2019 yuzu Emulator Project
|
||||||
@@ -28,14 +28,21 @@ set(GIT_DESC ${BUILD_VERSION})
|
|||||||
|
|
||||||
# Generate cpp with Git revision from template
|
# Generate cpp with Git revision from template
|
||||||
# Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well
|
# Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well
|
||||||
set(REPO_NAME "Eden")
|
|
||||||
set(BUILD_ID ${GIT_REFSPEC})
|
|
||||||
set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION} ")
|
|
||||||
set(CXX_COMPILER "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
|
|
||||||
|
|
||||||
# Auto-updater metadata! Must somewhat mirror GitHub API endpoint
|
# Auto-updater metadata! Must somewhat mirror GitHub API endpoint
|
||||||
set(BUILD_AUTO_UPDATE_WEBSITE "https://github.com")
|
set(BUILD_AUTO_UPDATE_WEBSITE "https://github.com")
|
||||||
set(BUILD_AUTO_UPDATE_API "http://api.github.com")
|
set(BUILD_AUTO_UPDATE_API "http://api.github.com")
|
||||||
|
|
||||||
|
if (NIGHTLY_BUILD)
|
||||||
|
set(BUILD_AUTO_UPDATE_REPO "Eden-CI/Nightly")
|
||||||
|
set(REPO_NAME "Eden Nightly")
|
||||||
|
else()
|
||||||
set(BUILD_AUTO_UPDATE_REPO "eden-emulator/Releases")
|
set(BUILD_AUTO_UPDATE_REPO "eden-emulator/Releases")
|
||||||
|
set(REPO_NAME "Eden")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(BUILD_ID ${GIT_REFSPEC})
|
||||||
|
set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION} ")
|
||||||
|
set(CXX_COMPILER "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
|
||||||
|
|
||||||
configure_file(scm_rev.cpp.in scm_rev.cpp @ONLY)
|
configure_file(scm_rev.cpp.in scm_rev.cpp @ONLY)
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ if (YUZU_STATIC_BUILD)
|
|||||||
add_compile_definitions(QT_STATICPLUGIN)
|
add_compile_definitions(QT_STATICPLUGIN)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (NIGHTLY_BUILD)
|
||||||
|
add_compile_definitions(NIGHTLY_BUILD)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Set compilation flags
|
# Set compilation flags
|
||||||
if (MSVC AND NOT CXX_CLANG)
|
if (MSVC AND NOT CXX_CLANG)
|
||||||
set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING "" FORCE)
|
set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING "" FORCE)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
// import android.annotation.SuppressLint
|
// import android.annotation.SuppressLint
|
||||||
|
import com.android.build.gradle.api.ApplicationVariant
|
||||||
import kotlin.collections.setOf
|
import kotlin.collections.setOf
|
||||||
import org.jlleitschuh.gradle.ktlint.reporter.ReporterType
|
import org.jlleitschuh.gradle.ktlint.reporter.ReporterType
|
||||||
import com.github.triplet.gradle.androidpublisher.ReleaseStatus
|
import com.github.triplet.gradle.androidpublisher.ReleaseStatus
|
||||||
@@ -37,6 +38,9 @@ android {
|
|||||||
compileSdkVersion = "android-36"
|
compileSdkVersion = "android-36"
|
||||||
ndkVersion = "28.2.13676358"
|
ndkVersion = "28.2.13676358"
|
||||||
|
|
||||||
|
val isNightly =
|
||||||
|
providers.gradleProperty("nightly").orNull?.toBooleanStrictOrNull() ?: false
|
||||||
|
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
viewBinding = true
|
viewBinding = true
|
||||||
}
|
}
|
||||||
@@ -71,6 +75,7 @@ android {
|
|||||||
val extraCMakeArgs =
|
val extraCMakeArgs =
|
||||||
(project.findProperty("YUZU_ANDROID_ARGS") as String?)?.split("\\s+".toRegex())
|
(project.findProperty("YUZU_ANDROID_ARGS") as String?)?.split("\\s+".toRegex())
|
||||||
?: emptyList()
|
?: emptyList()
|
||||||
|
|
||||||
arguments.addAll(
|
arguments.addAll(
|
||||||
listOf(
|
listOf(
|
||||||
"-DENABLE_QT=0", // Don't use QT
|
"-DENABLE_QT=0", // Don't use QT
|
||||||
@@ -89,6 +94,13 @@ android {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (isNightly) {
|
||||||
|
arguments.addAll(listOf(
|
||||||
|
"-DENABLE_UPDATE_CHECKER=ON",
|
||||||
|
"-DNIGHTLY_BUILD=ON",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
abiFilters("arm64-v8a")
|
abiFilters("arm64-v8a")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,7 +137,12 @@ android {
|
|||||||
signingConfigs.getByName("default")
|
signingConfigs.getByName("default")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isNightly) {
|
||||||
|
applicationIdSuffix = ".nightly"
|
||||||
|
manifestPlaceholders += mapOf("appNameSuffix" to " Nightly")
|
||||||
|
} else {
|
||||||
manifestPlaceholders += mapOf("appNameSuffix" to "")
|
manifestPlaceholders += mapOf("appNameSuffix" to "")
|
||||||
|
}
|
||||||
|
|
||||||
isMinifyEnabled = true
|
isMinifyEnabled = true
|
||||||
isDebuggable = false
|
isDebuggable = false
|
||||||
@@ -239,6 +256,15 @@ android {
|
|||||||
path = file("${edenDir}/CMakeLists.txt")
|
path = file("${edenDir}/CMakeLists.txt")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
productFlavors.all {
|
||||||
|
val currentName = manifestPlaceholders["appNameBase"] as? String ?: "Eden"
|
||||||
|
val suffix = if (isNightly) " Nightly" else ""
|
||||||
|
|
||||||
|
// apply nightly suffix I/A
|
||||||
|
resValue("string", "app_name_suffixed", "$currentName$suffix")
|
||||||
|
resValue("string", "app_name", "Eden$suffix")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
idea {
|
idea {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
@@ -218,7 +218,7 @@ object NativeLibrary {
|
|||||||
/**
|
/**
|
||||||
* Checks for available updates.
|
* Checks for available updates.
|
||||||
*/
|
*/
|
||||||
external fun checkForUpdate(): String?
|
external fun checkForUpdate(): Array<String>?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the URL to the release page
|
* Return the URL to the release page
|
||||||
@@ -228,13 +228,18 @@ object NativeLibrary {
|
|||||||
/**
|
/**
|
||||||
* Return the URL to download the APK for the given version
|
* Return the URL to download the APK for the given version
|
||||||
*/
|
*/
|
||||||
external fun getUpdateApkUrl(version: String, packageId: String): String
|
external fun getUpdateApkUrl(tag: String, artifact: String, packageId: String): String
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the update checker is enabled through CMAKE options.
|
* Returns whether the update checker is enabled through CMAKE options.
|
||||||
*/
|
*/
|
||||||
external fun isUpdateCheckerEnabled(): Boolean
|
external fun isUpdateCheckerEnabled(): Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this is a nightly build.
|
||||||
|
*/
|
||||||
|
external fun isNightlyBuild(): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the build version generated by CMake (BUILD_VERSION).
|
* Returns the build version generated by CMake (BUILD_VERSION).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.ui.main
|
package org.yuzu.yuzu_emu.ui.main
|
||||||
@@ -183,18 +183,26 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
val latestVersion = NativeLibrary.checkForUpdate()
|
val latestVersion = NativeLibrary.checkForUpdate()
|
||||||
if (latestVersion != null) {
|
if (latestVersion != null) {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
showUpdateDialog(latestVersion)
|
val tag: String = latestVersion[0]
|
||||||
|
val name: String = latestVersion[1]
|
||||||
|
showUpdateDialog(tag, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showUpdateDialog(version: String) {
|
private fun showUpdateDialog(tag: String, name: String) {
|
||||||
MaterialAlertDialogBuilder(this)
|
MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.update_available)
|
.setTitle(R.string.update_available)
|
||||||
.setMessage(getString(R.string.update_available_description, version))
|
.setMessage(getString(R.string.update_available_description, name))
|
||||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||||
downloadAndInstallUpdate(version)
|
var artifact = tag
|
||||||
|
// Nightly builds have a slightly different format
|
||||||
|
if (NativeLibrary.isNightlyBuild()) {
|
||||||
|
val splitTag = tag.split('.')
|
||||||
|
artifact = splitTag.subList(1, splitTag.size - 1).joinToString(".")
|
||||||
|
}
|
||||||
|
downloadAndInstallUpdate(tag, artifact)
|
||||||
}
|
}
|
||||||
.setNeutralButton(R.string.cancel) { dialog, _ ->
|
.setNeutralButton(R.string.cancel) { dialog, _ ->
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
@@ -207,11 +215,11 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun downloadAndInstallUpdate(version: String) {
|
private fun downloadAndInstallUpdate(version: String, artifact: String) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val packageId = applicationContext.packageName
|
val packageId = applicationContext.packageName
|
||||||
val apkUrl = NativeLibrary.getUpdateApkUrl(version, packageId)
|
val apkUrl = NativeLibrary.getUpdateApkUrl(version, artifact, packageId)
|
||||||
val apkFile = File(cacheDir, "update-$version.apk")
|
val apkFile = File(cacheDir, "update-$artifact.apk")
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
showDownloadProgressDialog()
|
showDownloadProgressDialog()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
@@ -1595,7 +1595,6 @@ JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_updatePowerState(
|
|||||||
g_has_battery.store(hasBattery, std::memory_order_relaxed);
|
g_has_battery.store(hasBattery, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return #ifdef ENABLE_UPDATE_CHECKER
|
|
||||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_isUpdateCheckerEnabled(
|
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_isUpdateCheckerEnabled(
|
||||||
JNIEnv* env,
|
JNIEnv* env,
|
||||||
jobject obj) {
|
jobject obj) {
|
||||||
@@ -1606,24 +1605,49 @@ JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_isUpdateChecker
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_isNightlyBuild(
|
||||||
|
JNIEnv* env,
|
||||||
|
jobject obj) {
|
||||||
|
#ifdef NIGHTLY_BUILD
|
||||||
|
return JNI_TRUE;
|
||||||
|
#else
|
||||||
|
return JNI_FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_UPDATE_CHECKER
|
#ifdef ENABLE_UPDATE_CHECKER
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_checkForUpdate(
|
JNIEXPORT jobjectArray JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_checkForUpdate(
|
||||||
JNIEnv* env,
|
JNIEnv* env,
|
||||||
jobject obj) {
|
jobject obj) {
|
||||||
const bool is_prerelease = ((strstr(Common::g_build_version, "pre-alpha") != nullptr) ||
|
const bool is_prerelease = ((strstr(Common::g_build_version, "pre-alpha") != nullptr) ||
|
||||||
(strstr(Common::g_build_version, "alpha") != nullptr) ||
|
(strstr(Common::g_build_version, "alpha") != nullptr) ||
|
||||||
(strstr(Common::g_build_version, "beta") != nullptr) ||
|
(strstr(Common::g_build_version, "beta") != nullptr) ||
|
||||||
(strstr(Common::g_build_version, "rc") != nullptr));
|
(strstr(Common::g_build_version, "rc") != nullptr));
|
||||||
const std::optional<std::string> latest_release_tag =
|
const std::optional<UpdateChecker::Update> release =
|
||||||
UpdateChecker::GetLatestRelease(is_prerelease);
|
UpdateChecker::GetLatestRelease(is_prerelease);
|
||||||
|
|
||||||
if (latest_release_tag && latest_release_tag.value() != Common::g_build_version) {
|
if (!release || release->tag == Common::g_build_version) {
|
||||||
return env->NewStringUTF(latest_release_tag.value().c_str());
|
|
||||||
}
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string tag = release->tag;
|
||||||
|
const std::string name = release->name;
|
||||||
|
|
||||||
|
jobjectArray result = env->NewObjectArray(2, env->FindClass("java/lang/String"), nullptr);
|
||||||
|
|
||||||
|
const jstring jtag = env->NewStringUTF(tag.c_str());
|
||||||
|
const jstring jname = env->NewStringUTF(name.c_str());
|
||||||
|
|
||||||
|
env->SetObjectArrayElement(result, 0, jtag);
|
||||||
|
env->SetObjectArrayElement(result, 1, jname);
|
||||||
|
env->DeleteLocalRef(jtag);
|
||||||
|
env->DeleteLocalRef(jname);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateUrl(
|
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateUrl(
|
||||||
JNIEnv* env,
|
JNIEnv* env,
|
||||||
jobject obj,
|
jobject obj,
|
||||||
@@ -1640,9 +1664,11 @@ JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateUrl(
|
|||||||
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateApkUrl(
|
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateApkUrl(
|
||||||
JNIEnv* env,
|
JNIEnv* env,
|
||||||
jobject obj,
|
jobject obj,
|
||||||
jstring version,
|
jstring tag,
|
||||||
|
jstring artifact,
|
||||||
jstring packageId) {
|
jstring packageId) {
|
||||||
const char* version_str = env->GetStringUTFChars(version, nullptr);
|
const char* version_str = env->GetStringUTFChars(tag, nullptr);
|
||||||
|
const char* artifact_str = env->GetStringUTFChars(artifact, nullptr);
|
||||||
const char* package_id_str = env->GetStringUTFChars(packageId, nullptr);
|
const char* package_id_str = env->GetStringUTFChars(packageId, nullptr);
|
||||||
|
|
||||||
std::string variant;
|
std::string variant;
|
||||||
@@ -1653,7 +1679,11 @@ JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateApkUrl(
|
|||||||
} else if (package_id.find("com.miHoYo.Yuanshen") != std::string::npos) {
|
} else if (package_id.find("com.miHoYo.Yuanshen") != std::string::npos) {
|
||||||
variant = "optimized";
|
variant = "optimized";
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef ARCHITECTURE_arm64
|
||||||
variant = "standard";
|
variant = "standard";
|
||||||
|
#else
|
||||||
|
variant = "chromeos";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string apk_filename = fmt::format("Eden-Android-{}-{}.apk", version_str, variant);
|
const std::string apk_filename = fmt::format("Eden-Android-{}-{}.apk", version_str, variant);
|
||||||
@@ -1663,7 +1693,7 @@ JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateApkUrl(
|
|||||||
version_str,
|
version_str,
|
||||||
apk_filename);
|
apk_filename);
|
||||||
|
|
||||||
env->ReleaseStringUTFChars(version, version_str);
|
env->ReleaseStringUTFChars(tag, version_str);
|
||||||
env->ReleaseStringUTFChars(packageId, package_id_str);
|
env->ReleaseStringUTFChars(packageId, package_id_str);
|
||||||
return env->NewStringUTF(url.c_str());
|
return env->NewStringUTF(url.c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
@@ -78,7 +78,7 @@ std::optional<std::string> UpdateChecker::GetResponse(std::string url, std::stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> UpdateChecker::GetLatestRelease(bool include_prereleases) {
|
std::optional<UpdateChecker::Update> UpdateChecker::GetLatestRelease(bool include_prereleases) {
|
||||||
const auto update_check_url = std::string{Common::g_build_auto_update_api};
|
const auto update_check_url = std::string{Common::g_build_auto_update_api};
|
||||||
std::string update_check_path = fmt::format("/repos/{}",
|
std::string update_check_path = fmt::format("/repos/{}",
|
||||||
std::string{Common::g_build_auto_update_repo});
|
std::string{Common::g_build_auto_update_repo});
|
||||||
@@ -96,6 +96,9 @@ std::optional<std::string> UpdateChecker::GetLatestRelease(bool include_prerelea
|
|||||||
|
|
||||||
const std::string latest_tag
|
const std::string latest_tag
|
||||||
= nlohmann::json::parse(tags_response.value()).at(0).at("name");
|
= nlohmann::json::parse(tags_response.value()).at(0).at("name");
|
||||||
|
const std::string latest_name =
|
||||||
|
nlohmann::json::parse(releases_response.value()).at(0).at("name");
|
||||||
|
|
||||||
const bool latest_tag_has_release = releases_response.value().find(
|
const bool latest_tag_has_release = releases_response.value().find(
|
||||||
fmt::format("\"{}\"", latest_tag))
|
fmt::format("\"{}\"", latest_tag))
|
||||||
!= std::string::npos;
|
!= std::string::npos;
|
||||||
@@ -105,7 +108,7 @@ std::optional<std::string> UpdateChecker::GetLatestRelease(bool include_prerelea
|
|||||||
if (!latest_tag_has_release)
|
if (!latest_tag_has_release)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return latest_tag;
|
return Update{latest_tag, latest_name};
|
||||||
} else { // This is a stable release, only check for other stable releases.
|
} else { // This is a stable release, only check for other stable releases.
|
||||||
update_check_path += "/releases/latest";
|
update_check_path += "/releases/latest";
|
||||||
const auto response = UpdateChecker::GetResponse(update_check_url, update_check_path);
|
const auto response = UpdateChecker::GetResponse(update_check_url, update_check_path);
|
||||||
@@ -114,7 +117,9 @@ std::optional<std::string> UpdateChecker::GetLatestRelease(bool include_prerelea
|
|||||||
return {};
|
return {};
|
||||||
|
|
||||||
const std::string latest_tag = nlohmann::json::parse(response.value()).at("tag_name");
|
const std::string latest_tag = nlohmann::json::parse(response.value()).at("tag_name");
|
||||||
return latest_tag;
|
const std::string latest_name = nlohmann::json::parse(response.value()).at("name");
|
||||||
|
|
||||||
|
return Update{latest_tag, latest_name};
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (nlohmann::detail::out_of_range &) {
|
} catch (nlohmann::detail::out_of_range &) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
@@ -11,6 +11,12 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace UpdateChecker {
|
namespace UpdateChecker {
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
std::string tag;
|
||||||
|
std::string name;
|
||||||
|
} Update;
|
||||||
|
|
||||||
std::optional<std::string> GetResponse(std::string url, std::string path);
|
std::optional<std::string> GetResponse(std::string url, std::string path);
|
||||||
std::optional<std::string> GetLatestRelease(bool include_prereleases);
|
std::optional<Update> GetLatestRelease(bool include_prereleases);
|
||||||
} // namespace UpdateChecker
|
} // namespace UpdateChecker
|
||||||
|
|||||||
@@ -516,17 +516,17 @@ MainWindow::MainWindow(bool has_broken_vulkan)
|
|||||||
|
|
||||||
#ifdef ENABLE_UPDATE_CHECKER
|
#ifdef ENABLE_UPDATE_CHECKER
|
||||||
if (UISettings::values.check_for_updates) {
|
if (UISettings::values.check_for_updates) {
|
||||||
update_future = QtConcurrent::run([]() -> QString {
|
update_future = QtConcurrent::run([]() -> UpdateChecker::Update {
|
||||||
const bool is_prerelease = ((strstr(Common::g_build_version, "pre-alpha") != NULL) ||
|
const bool is_prerelease = ((strstr(Common::g_build_version, "pre-alpha") != NULL) ||
|
||||||
(strstr(Common::g_build_version, "alpha") != NULL) ||
|
(strstr(Common::g_build_version, "alpha") != NULL) ||
|
||||||
(strstr(Common::g_build_version, "beta") != NULL) ||
|
(strstr(Common::g_build_version, "beta") != NULL) ||
|
||||||
(strstr(Common::g_build_version, "rc") != NULL));
|
(strstr(Common::g_build_version, "rc") != NULL));
|
||||||
const std::optional<std::string> latest_release_tag =
|
const std::optional<UpdateChecker::Update> latest_release_tag =
|
||||||
UpdateChecker::GetLatestRelease(is_prerelease);
|
UpdateChecker::GetLatestRelease(is_prerelease);
|
||||||
if (latest_release_tag && latest_release_tag.value() != Common::g_build_version) {
|
if (latest_release_tag && latest_release_tag->tag != Common::g_build_version) {
|
||||||
return QString::fromStdString(latest_release_tag.value());
|
return latest_release_tag.value();
|
||||||
}
|
}
|
||||||
return QString{};
|
return UpdateChecker::Update{};
|
||||||
});
|
});
|
||||||
update_watcher.connect(&update_watcher, &QFutureWatcher<QString>::finished, this,
|
update_watcher.connect(&update_watcher, &QFutureWatcher<QString>::finished, this,
|
||||||
&MainWindow::OnEmulatorUpdateAvailable);
|
&MainWindow::OnEmulatorUpdateAvailable);
|
||||||
@@ -4020,8 +4020,8 @@ void MainWindow::OnCaptureScreenshot() {
|
|||||||
|
|
||||||
#ifdef ENABLE_UPDATE_CHECKER
|
#ifdef ENABLE_UPDATE_CHECKER
|
||||||
void MainWindow::OnEmulatorUpdateAvailable() {
|
void MainWindow::OnEmulatorUpdateAvailable() {
|
||||||
QString version_string = update_future.result();
|
UpdateChecker::Update version = update_future.result();
|
||||||
if (version_string.isEmpty())
|
if (version.tag.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QMessageBox update_prompt(this);
|
QMessageBox update_prompt(this);
|
||||||
@@ -4030,14 +4030,14 @@ void MainWindow::OnEmulatorUpdateAvailable() {
|
|||||||
update_prompt.addButton(QMessageBox::Yes);
|
update_prompt.addButton(QMessageBox::Yes);
|
||||||
update_prompt.addButton(QMessageBox::Ignore);
|
update_prompt.addButton(QMessageBox::Ignore);
|
||||||
update_prompt.setText(
|
update_prompt.setText(
|
||||||
tr("Download the %1 update?").arg(version_string));
|
tr("Download %1?").arg(version.name));
|
||||||
update_prompt.exec();
|
update_prompt.exec();
|
||||||
if (update_prompt.button(QMessageBox::Yes) == update_prompt.clickedButton()) {
|
if (update_prompt.button(QMessageBox::Yes) == update_prompt.clickedButton()) {
|
||||||
auto const full_url = fmt::format("{}/{}/releases/tag/",
|
auto const full_url = fmt::format("{}/{}/releases/tag/",
|
||||||
std::string{Common::g_build_auto_update_website},
|
std::string{Common::g_build_auto_update_website},
|
||||||
std::string{Common::g_build_auto_update_repo}
|
std::string{Common::g_build_auto_update_repo}
|
||||||
);
|
);
|
||||||
QDesktopServices::openUrl(QUrl(QString::fromStdString(full_url) + version_string));
|
QDesktopServices::openUrl(QUrl(QString::fromStdString(full_url + version.tag)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "frontend_common/content_manager.h"
|
#include "frontend_common/content_manager.h"
|
||||||
|
#include "frontend_common/update_checker.h"
|
||||||
#include "input_common/drivers/tas_input.h"
|
#include "input_common/drivers/tas_input.h"
|
||||||
#include "qt_common/config/qt_config.h"
|
#include "qt_common/config/qt_config.h"
|
||||||
#include "qt_common/util/game.h"
|
#include "qt_common/util/game.h"
|
||||||
@@ -471,8 +472,8 @@ private:
|
|||||||
std::shared_ptr<InputCommon::InputSubsystem> input_subsystem;
|
std::shared_ptr<InputCommon::InputSubsystem> input_subsystem;
|
||||||
|
|
||||||
#ifdef ENABLE_UPDATE_CHECKER
|
#ifdef ENABLE_UPDATE_CHECKER
|
||||||
QFuture<QString> update_future;
|
QFuture<UpdateChecker::Update> update_future;
|
||||||
QFutureWatcher<QString> update_watcher;
|
QFutureWatcher<UpdateChecker::Update> update_watcher;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MultiplayerState* multiplayer_state = nullptr;
|
MultiplayerState* multiplayer_state = nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user