[frontend] refactor: extract common firmware & key functions #38
39 changed files with 1146 additions and 1078 deletions
|
@ -15,6 +15,7 @@ import android.view.Surface
|
|||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.Keep
|
||||
import androidx.core.net.toUri
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import net.swiftzer.semver.SemVer
|
||||
import java.lang.ref.WeakReference
|
||||
|
@ -27,6 +28,7 @@ import org.yuzu.yuzu_emu.model.InstallResult
|
|||
import org.yuzu.yuzu_emu.model.Patch
|
||||
import org.yuzu.yuzu_emu.model.GameVerificationResult
|
||||
import org.yuzu.yuzu_emu.network.NetPlayManager
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Class which contains methods that interact
|
||||
|
@ -102,6 +104,21 @@ object NativeLibrary {
|
|||
FileUtil.getFilename(Uri.parse(path))
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
fun copyFileToStorage(source: String, destdir: String): Boolean {
|
||||
return FileUtil.copyUriToInternalStorage(
|
||||
source.toUri(),
|
||||
destdir
|
||||
) != null
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
fun getFileExtension(source: String): String {
|
||||
return FileUtil.getExtension(source.toUri())
|
||||
}
|
||||
|
||||
external fun setAppDirectory(directory: String)
|
||||
|
||||
/**
|
||||
|
@ -415,18 +432,29 @@ object NativeLibrary {
|
|||
*/
|
||||
external fun firmwareVersion(): String
|
||||
|
||||
fun isFirmwareSupported(): Boolean {
|
||||
var version: SemVer
|
||||
/**
|
||||
* Verifies installed firmware.
|
||||
*
|
||||
* @return The result code.
|
||||
*/
|
||||
external fun verifyFirmware(): Int
|
||||
|
||||
try {
|
||||
version = SemVer.parse(firmwareVersion())
|
||||
} catch (_: Exception) {
|
||||
return false
|
||||
}
|
||||
val max = SemVer(19, 0, 1)
|
||||
/**
|
||||
* Check if a game requires firmware to be playable.
|
||||
*
|
||||
* @param programId The game's Program ID.
|
||||
* @return Whether or not the game requires firmware to be playable.
|
||||
*/
|
||||
external fun gameRequiresFirmware(programId: String): Boolean
|
||||
|
||||
return version <= max
|
||||
}
|
||||
/**
|
||||
* Installs keys from the specified path.
|
||||
*
|
||||
* @param path The path to install keys from.
|
||||
* @param ext What extension the keys should have.
|
||||
* @return The result code.
|
||||
*/
|
||||
external fun installKeys(path: String, ext: String): Int
|
||||
|
||||
/**
|
||||
* Checks the PatchManager for any addons that are available
|
||||
|
|
|
@ -3,11 +3,16 @@
|
|||
|
||||
package org.yuzu.yuzu_emu.adapters
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.net.Uri
|
||||
import android.text.Html
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
|
@ -33,6 +38,10 @@ import org.yuzu.yuzu_emu.utils.GameIconUtils
|
|||
import org.yuzu.yuzu_emu.utils.ViewUtils.marquee
|
||||
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.content.edit
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.yuzu.yuzu_emu.NativeLibrary
|
||||
|
||||
class GameAdapter(private val activity: AppCompatActivity) :
|
||||
AbstractDiffAdapter<Game, GameAdapter.GameViewHolder>(exact = false) {
|
||||
|
@ -171,8 +180,9 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
|||
fun onClick(game: Game) {
|
||||
val gameExists = DocumentFile.fromSingleUri(
|
||||
YuzuApplication.appContext,
|
||||
Uri.parse(game.path)
|
||||
game.path.toUri()
|
||||
)?.exists() == true
|
||||
|
||||
if (!gameExists) {
|
||||
Toast.makeText(
|
||||
YuzuApplication.appContext,
|
||||
|
@ -184,29 +194,49 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
|||
return
|
||||
}
|
||||
|
||||
val preferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
||||
preferences.edit()
|
||||
.putLong(
|
||||
game.keyLastPlayedTime,
|
||||
System.currentTimeMillis()
|
||||
)
|
||||
.apply()
|
||||
|
||||
activity.lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val shortcut =
|
||||
ShortcutInfoCompat.Builder(YuzuApplication.appContext, game.path)
|
||||
.setShortLabel(game.title)
|
||||
.setIcon(GameIconUtils.getShortcutIcon(activity, game))
|
||||
.setIntent(game.launchIntent)
|
||||
.build()
|
||||
ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
|
||||
val launch: () -> Unit = {
|
||||
val preferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
||||
preferences.edit {
|
||||
putLong(
|
||||
game.keyLastPlayedTime,
|
||||
System.currentTimeMillis()
|
||||
)
|
||||
}
|
||||
|
||||
activity.lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val shortcut =
|
||||
ShortcutInfoCompat.Builder(YuzuApplication.appContext, game.path)
|
||||
.setShortLabel(game.title)
|
||||
.setIcon(GameIconUtils.getShortcutIcon(activity, game))
|
||||
.setIntent(game.launchIntent)
|
||||
.build()
|
||||
ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
|
||||
}
|
||||
}
|
||||
|
||||
val action = HomeNavigationDirections.actionGlobalEmulationActivity(game, true)
|
||||
binding.root.findNavController().navigate(action)
|
||||
}
|
||||
|
||||
val action = HomeNavigationDirections.actionGlobalEmulationActivity(game, true)
|
||||
binding.root.findNavController().navigate(action)
|
||||
if (NativeLibrary.gameRequiresFirmware(game.programId) && !NativeLibrary.isFirmwareAvailable()) {
|
||||
MaterialAlertDialogBuilder(activity)
|
||||
.setTitle(R.string.loader_requires_firmware)
|
||||
.setMessage(
|
||||
Html.fromHtml(
|
||||
activity.getString(R.string.loader_requires_firmware_description),
|
||||
Html.FROM_HTML_MODE_LEGACY
|
||||
)
|
||||
)
|
||||
.setPositiveButton(android.R.string.ok) { _: DialogInterface?, _: Int ->
|
||||
launch()
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel) { _,_ -> }
|
||||
.show()
|
||||
} else {
|
||||
launch()
|
||||
}
|
||||
}
|
||||
|
||||
fun onLongClick(game: Game): Boolean {
|
||||
|
|
|
@ -264,8 +264,6 @@ class DriverFetcherFragment : Fragment() {
|
|||
}
|
||||
|
||||
releases.add(release)
|
||||
|
||||
println(release.publishTime)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ class HomeSettingsFragment : Fragment() {
|
|||
binding.root.findNavController()
|
||||
.navigate(R.id.action_homeSettingsFragment_to_appletLauncherFragment)
|
||||
},
|
||||
{ NativeLibrary.isFirmwareAvailable() && NativeLibrary.isFirmwareSupported() },
|
||||
{ NativeLibrary.isFirmwareAvailable() },
|
||||
R.string.applets_error_firmware,
|
||||
R.string.applets_error_description
|
||||
)
|
||||
|
|
|
@ -352,7 +352,7 @@ class SetupFragment : Fragment() {
|
|||
val getProdKey =
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result != null) {
|
||||
mainActivity.processKey(result)
|
||||
mainActivity.processKey(result, "keys")
|
||||
if (NativeLibrary.areKeysPresent()) {
|
||||
keyCallback.onStepCompleted()
|
||||
}
|
||||
|
|
|
@ -47,9 +47,6 @@ import info.debatty.java.stringsimilarity.Jaccard
|
|||
import info.debatty.java.stringsimilarity.JaroWinkler
|
||||
import java.util.Locale
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||
import android.view.ViewParent
|
||||
import androidx.core.view.doOnNextLayout
|
||||
|
||||
class GamesFragment : Fragment() {
|
||||
|
@ -151,7 +148,7 @@ class GamesFragment : Fragment() {
|
|||
)
|
||||
}
|
||||
gamesViewModel.games.collect(viewLifecycleOwner) {
|
||||
if (it.size > 0) {
|
||||
if (it.isNotEmpty()) {
|
||||
setAdapter(it)
|
||||
}
|
||||
}
|
||||
|
@ -361,7 +358,7 @@ class GamesFragment : Fragment() {
|
|||
|
||||
popup.setOnMenuItemClickListener { item ->
|
||||
currentFilter = item.itemId
|
||||
preferences.edit().putInt(PREF_SORT_TYPE, currentFilter).apply()
|
||||
preferences.edit { putInt(PREF_SORT_TYPE, currentFilter) }
|
||||
filterAndSearch()
|
||||
true
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ package org.yuzu.yuzu_emu.ui.main
|
|||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.provider.OpenableColumns
|
||||
import android.view.View
|
||||
import android.view.ViewGroup.MarginLayoutParams
|
||||
import android.view.WindowManager
|
||||
|
@ -47,6 +49,7 @@ import java.io.BufferedOutputStream
|
|||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipInputStream
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.net.toFile
|
||||
|
||||
class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
|
@ -70,10 +73,12 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
val granted = permissions.entries.all { it.value }
|
||||
if (granted) {
|
||||
// Permissions were granted.
|
||||
Toast.makeText(this, R.string.bluetooth_permissions_granted, Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.bluetooth_permissions_granted, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
} else {
|
||||
// Permissions were denied.
|
||||
Toast.makeText(this, R.string.bluetooth_permissions_denied, Toast.LENGTH_LONG).show()
|
||||
Toast.makeText(this, R.string.bluetooth_permissions_denied, Toast.LENGTH_LONG)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,7 +99,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
val splashScreen = installSplashScreen()
|
||||
splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }
|
||||
|
@ -105,13 +110,13 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
NativeLibrary.initMultiplayer()
|
||||
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
|
||||
|
||||
|
||||
setContentView(binding.root)
|
||||
|
||||
|
||||
|
||||
|
||||
checkAndRequestBluetoothPermissions()
|
||||
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
checkedDecryption = savedInstanceState.getBoolean(CHECKED_DECRYPTION)
|
||||
checkedFirmware = savedInstanceState.getBoolean(CHECKED_FIRMWARE)
|
||||
|
@ -146,22 +151,16 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
binding.statusBarShade.setBackgroundColor(
|
||||
ThemeHelper.getColorWithOpacity(
|
||||
MaterialColors.getColor(
|
||||
binding.root,
|
||||
com.google.android.material.R.attr.colorSurface
|
||||
),
|
||||
ThemeHelper.SYSTEM_BAR_ALPHA
|
||||
binding.root, com.google.android.material.R.attr.colorSurface
|
||||
), ThemeHelper.SYSTEM_BAR_ALPHA
|
||||
)
|
||||
)
|
||||
if (InsetsHelper.getSystemGestureType(applicationContext) !=
|
||||
InsetsHelper.GESTURE_NAVIGATION
|
||||
) {
|
||||
if (InsetsHelper.getSystemGestureType(applicationContext) != InsetsHelper.GESTURE_NAVIGATION) {
|
||||
binding.navigationBarShade.setBackgroundColor(
|
||||
ThemeHelper.getColorWithOpacity(
|
||||
MaterialColors.getColor(
|
||||
binding.root,
|
||||
com.google.android.material.R.attr.colorSurface
|
||||
),
|
||||
ThemeHelper.SYSTEM_BAR_ALPHA
|
||||
binding.root, com.google.android.material.R.attr.colorSurface
|
||||
), ThemeHelper.SYSTEM_BAR_ALPHA
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -172,9 +171,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
|
||||
homeViewModel.statusBarShadeVisible.collect(this) { showStatusBarShade(it) }
|
||||
homeViewModel.contentToInstall.collect(
|
||||
this,
|
||||
resetState = { homeViewModel.setContentToInstall(null) }
|
||||
) {
|
||||
this, resetState = { homeViewModel.setContentToInstall(null) }) {
|
||||
if (it != null) {
|
||||
installContent(it)
|
||||
}
|
||||
|
@ -183,7 +180,8 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
if (it) checkKeys()
|
||||
}
|
||||
|
||||
homeViewModel.checkFirmware.collect(this, resetState = { homeViewModel.setCheckFirmware(false) }) {
|
||||
homeViewModel.checkFirmware.collect(
|
||||
this, resetState = { homeViewModel.setCheckFirmware(false) }) {
|
||||
if (it) checkFirmware()
|
||||
}
|
||||
|
||||
|
@ -203,12 +201,10 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
negativeButtonTitleId = R.string.close,
|
||||
showNegativeButton = true,
|
||||
positiveAction = {
|
||||
PreferenceManager.getDefaultSharedPreferences(applicationContext)
|
||||
.edit() {
|
||||
putBoolean(Settings.PREF_SHOULD_SHOW_PRE_ALPHA_WARNING, false)
|
||||
}
|
||||
}
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
PreferenceManager.getDefaultSharedPreferences(applicationContext).edit() {
|
||||
putBoolean(Settings.PREF_SHOULD_SHOW_PRE_ALPHA_WARNING, false)
|
||||
}
|
||||
}).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,15 +224,18 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
}
|
||||
|
||||
private fun checkFirmware() {
|
||||
if (!NativeLibrary.isFirmwareAvailable() || !NativeLibrary.isFirmwareSupported()) {
|
||||
MessageDialogFragment.newInstance(
|
||||
titleId = R.string.firmware_missing,
|
||||
descriptionId = R.string.firmware_missing_description,
|
||||
helpLinkId = R.string.firmware_missing_help
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
}
|
||||
}
|
||||
val resultCode: Int = NativeLibrary.verifyFirmware()
|
||||
if (resultCode == 0) return;
|
||||
|
||||
val resultString: String =
|
||||
resources.getStringArray(R.array.verifyFirmwareResults)[resultCode]
|
||||
|
||||
MessageDialogFragment.newInstance(
|
||||
titleId = R.string.firmware_invalid,
|
||||
descriptionString = resultString,
|
||||
helpLinkId = R.string.firmware_missing_help
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
|
@ -283,23 +282,22 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
super.onResume()
|
||||
}
|
||||
|
||||
private fun setInsets() =
|
||||
ViewCompat.setOnApplyWindowInsetsListener(
|
||||
binding.root
|
||||
) { _: View, windowInsets: WindowInsetsCompat ->
|
||||
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
val mlpStatusShade = binding.statusBarShade.layoutParams as MarginLayoutParams
|
||||
mlpStatusShade.height = insets.top
|
||||
binding.statusBarShade.layoutParams = mlpStatusShade
|
||||
private fun setInsets() = ViewCompat.setOnApplyWindowInsetsListener(
|
||||
binding.root
|
||||
) { _: View, windowInsets: WindowInsetsCompat ->
|
||||
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
val mlpStatusShade = binding.statusBarShade.layoutParams as MarginLayoutParams
|
||||
mlpStatusShade.height = insets.top
|
||||
binding.statusBarShade.layoutParams = mlpStatusShade
|
||||
|
||||
// The only situation where we care to have a nav bar shade is when it's at the bottom
|
||||
// of the screen where scrolling list elements can go behind it.
|
||||
val mlpNavShade = binding.navigationBarShade.layoutParams as MarginLayoutParams
|
||||
mlpNavShade.height = insets.bottom
|
||||
binding.navigationBarShade.layoutParams = mlpNavShade
|
||||
// The only situation where we care to have a nav bar shade is when it's at the bottom
|
||||
// of the screen where scrolling list elements can go behind it.
|
||||
val mlpNavShade = binding.navigationBarShade.layoutParams as MarginLayoutParams
|
||||
mlpNavShade.height = insets.bottom
|
||||
binding.navigationBarShade.layoutParams = mlpNavShade
|
||||
|
||||
windowInsets
|
||||
}
|
||||
windowInsets
|
||||
}
|
||||
|
||||
override fun setTheme(resId: Int) {
|
||||
super.setTheme(resId)
|
||||
|
@ -315,17 +313,14 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
|
||||
fun processGamesDir(result: Uri, calledFromGameFragment: Boolean = false) {
|
||||
contentResolver.takePersistableUriPermission(
|
||||
result,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
result, Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
|
||||
val uriString = result.toString()
|
||||
val folder = gamesViewModel.folders.value.firstOrNull { it.uriString == uriString }
|
||||
if (folder != null) {
|
||||
Toast.makeText(
|
||||
applicationContext,
|
||||
R.string.folder_already_added,
|
||||
Toast.LENGTH_SHORT
|
||||
applicationContext, R.string.folder_already_added, Toast.LENGTH_SHORT
|
||||
).show()
|
||||
return
|
||||
}
|
||||
|
@ -334,72 +329,50 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
.show(supportFragmentManager, AddGameFolderDialogFragment.TAG)
|
||||
}
|
||||
|
||||
val getProdKey =
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result != null) {
|
||||
processKey(result)
|
||||
}
|
||||
val getProdKey = registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result != null) {
|
||||
processKey(result, "keys")
|
||||
}
|
||||
|
||||
fun processKey(result: Uri): Boolean {
|
||||
if (FileUtil.getExtension(result) != "keys") {
|
||||
MessageDialogFragment.newInstance(
|
||||
this,
|
||||
titleId = R.string.reading_keys_failure,
|
||||
descriptionId = R.string.install_prod_keys_failure_extension_description
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
return false
|
||||
}
|
||||
|
||||
contentResolver.takePersistableUriPermission(
|
||||
result,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
|
||||
val dstPath = DirectoryInitialization.userDirectory + "/keys/"
|
||||
if (FileUtil.copyUriToInternalStorage(
|
||||
result,
|
||||
dstPath,
|
||||
"prod.keys"
|
||||
) != null
|
||||
) {
|
||||
if (NativeLibrary.reloadKeys()) {
|
||||
Toast.makeText(
|
||||
applicationContext,
|
||||
R.string.install_keys_success,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
homeViewModel.setCheckKeys(true)
|
||||
|
||||
val firstTimeSetup = PreferenceManager.getDefaultSharedPreferences(applicationContext)
|
||||
.getBoolean(Settings.PREF_FIRST_APP_LAUNCH, true)
|
||||
if (!firstTimeSetup) {
|
||||
homeViewModel.setCheckFirmware(true)
|
||||
}
|
||||
|
||||
gamesViewModel.reloadGames(true)
|
||||
return true
|
||||
} else {
|
||||
MessageDialogFragment.newInstance(
|
||||
this,
|
||||
titleId = R.string.invalid_keys_error,
|
||||
descriptionId = R.string.install_keys_failure_description,
|
||||
helpLinkId = R.string.dumping_keys_quickstart_link
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
val getFirmware =
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result == null) {
|
||||
return@registerForActivityResult
|
||||
}
|
||||
val getAmiiboKey = registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result != null) {
|
||||
processKey(result, "bin")
|
||||
}
|
||||
}
|
||||
|
||||
fun processKey(result: Uri, extension: String = "keys") {
|
||||
contentResolver.takePersistableUriPermission(
|
||||
result, Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
|
||||
val resultCode: Int = NativeLibrary.installKeys(result.toString(), extension);
|
||||
|
||||
if (resultCode == 0) {
|
||||
Toast.makeText(
|
||||
applicationContext, R.string.keys_install_success, Toast.LENGTH_SHORT
|
||||
).show()
|
||||
|
||||
gamesViewModel.reloadGames(true)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
val resultString: String =
|
||||
resources.getStringArray(R.array.installKeysResults)[resultCode]
|
||||
|
||||
MessageDialogFragment.newInstance(
|
||||
titleId = R.string.keys_failed,
|
||||
descriptionString = resultString,
|
||||
helpLinkId = R.string.keys_missing_help
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
}
|
||||
|
||||
val getFirmware = registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result != null) {
|
||||
processFirmware(result)
|
||||
}
|
||||
}
|
||||
|
||||
fun processFirmware(result: Uri, onComplete: (() -> Unit)? = null) {
|
||||
val filterNCA = FilenameFilter { _, dirName -> dirName.endsWith(".nca") }
|
||||
|
@ -409,15 +382,12 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
val cacheFirmwareDir = File("${cacheDir.path}/registered/")
|
||||
|
||||
ProgressDialogFragment.newInstance(
|
||||
this,
|
||||
R.string.firmware_installing
|
||||
this, R.string.firmware_installing
|
||||
) { progressCallback, _ ->
|
||||
var messageToShow: Any
|
||||
try {
|
||||
FileUtil.unzipToInternalStorage(
|
||||
result.toString(),
|
||||
cacheFirmwareDir,
|
||||
progressCallback
|
||||
result.toString(), cacheFirmwareDir, progressCallback
|
||||
)
|
||||
val unfilteredNumOfFiles = cacheFirmwareDir.list()?.size ?: -1
|
||||
val filteredNumOfFiles = cacheFirmwareDir.list(filterNCA)?.size ?: -2
|
||||
|
@ -448,10 +418,10 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
}
|
||||
|
||||
fun uninstallFirmware() {
|
||||
val firmwarePath = File(DirectoryInitialization.userDirectory + "/nand/system/Contents/registered/")
|
||||
val firmwarePath =
|
||||
File(DirectoryInitialization.userDirectory + "/nand/system/Contents/registered/")
|
||||
ProgressDialogFragment.newInstance(
|
||||
this,
|
||||
R.string.firmware_uninstalling
|
||||
this, R.string.firmware_uninstalling
|
||||
) { progressCallback, _ ->
|
||||
var messageToShow: Any
|
||||
try {
|
||||
|
@ -473,49 +443,6 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
messageToShow
|
||||
}.show(supportFragmentManager, ProgressDialogFragment.TAG)
|
||||
}
|
||||
val getAmiiboKey =
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result == null) {
|
||||
return@registerForActivityResult
|
||||
}
|
||||
|
||||
if (FileUtil.getExtension(result) != "bin") {
|
||||
MessageDialogFragment.newInstance(
|
||||
this,
|
||||
titleId = R.string.reading_keys_failure,
|
||||
descriptionId = R.string.install_amiibo_keys_failure_extension_description
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
return@registerForActivityResult
|
||||
}
|
||||
|
||||
contentResolver.takePersistableUriPermission(
|
||||
result,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
|
||||
val dstPath = DirectoryInitialization.userDirectory + "/keys/"
|
||||
if (FileUtil.copyUriToInternalStorage(
|
||||
result,
|
||||
dstPath,
|
||||
"key_retail.bin"
|
||||
) != null
|
||||
) {
|
||||
if (NativeLibrary.reloadKeys()) {
|
||||
Toast.makeText(
|
||||
applicationContext,
|
||||
R.string.install_keys_success,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
} else {
|
||||
MessageDialogFragment.newInstance(
|
||||
this,
|
||||
titleId = R.string.invalid_keys_error,
|
||||
descriptionId = R.string.install_keys_failure_description,
|
||||
helpLinkId = R.string.dumping_keys_quickstart_link
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val installGameUpdate = registerForActivityResult(
|
||||
ActivityResultContracts.OpenMultipleDocuments()
|
||||
|
@ -530,15 +457,12 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
}
|
||||
|
||||
ProgressDialogFragment.newInstance(
|
||||
this@MainActivity,
|
||||
R.string.verifying_content,
|
||||
false
|
||||
this@MainActivity, R.string.verifying_content, false
|
||||
) { _, _ ->
|
||||
var updatesMatchProgram = true
|
||||
for (document in documents) {
|
||||
val valid = NativeLibrary.doesUpdateMatchProgram(
|
||||
addonViewModel.game!!.programId,
|
||||
document.toString()
|
||||
addonViewModel.game!!.programId, document.toString()
|
||||
)
|
||||
if (!valid) {
|
||||
updatesMatchProgram = false
|
||||
|
@ -554,16 +478,14 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
titleId = R.string.content_install_notice,
|
||||
descriptionId = R.string.content_install_notice_description,
|
||||
positiveAction = { homeViewModel.setContentToInstall(documents) },
|
||||
negativeAction = {}
|
||||
)
|
||||
negativeAction = {})
|
||||
}
|
||||
}.show(supportFragmentManager, ProgressDialogFragment.TAG)
|
||||
}
|
||||
|
||||
private fun installContent(documents: List<Uri>) {
|
||||
ProgressDialogFragment.newInstance(
|
||||
this@MainActivity,
|
||||
R.string.installing_game_content
|
||||
this@MainActivity, R.string.installing_game_content
|
||||
) { progressCallback, messageCallback ->
|
||||
var installSuccess = 0
|
||||
var installOverwrite = 0
|
||||
|
@ -571,14 +493,11 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
var error = 0
|
||||
documents.forEach {
|
||||
messageCallback.invoke(FileUtil.getFilename(it))
|
||||
when (
|
||||
InstallResult.from(
|
||||
NativeLibrary.installFileToNand(
|
||||
it.toString(),
|
||||
progressCallback
|
||||
)
|
||||
when (InstallResult.from(
|
||||
NativeLibrary.installFileToNand(
|
||||
it.toString(), progressCallback
|
||||
)
|
||||
) {
|
||||
)) {
|
||||
InstallResult.Success -> {
|
||||
installSuccess += 1
|
||||
}
|
||||
|
@ -599,13 +518,12 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
|
||||
addonViewModel.refreshAddons()
|
||||
|
||||
val separator = System.getProperty("line.separator") ?: "\n"
|
||||
val separator = System.lineSeparator() ?: "\n"
|
||||
val installResult = StringBuilder()
|
||||
if (installSuccess > 0) {
|
||||
installResult.append(
|
||||
getString(
|
||||
R.string.install_game_content_success_install,
|
||||
installSuccess
|
||||
R.string.install_game_content_success_install, installSuccess
|
||||
)
|
||||
)
|
||||
installResult.append(separator)
|
||||
|
@ -613,8 +531,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
if (installOverwrite > 0) {
|
||||
installResult.append(
|
||||
getString(
|
||||
R.string.install_game_content_success_overwrite,
|
||||
installOverwrite
|
||||
R.string.install_game_content_success_overwrite, installOverwrite
|
||||
)
|
||||
)
|
||||
installResult.append(separator)
|
||||
|
@ -624,8 +541,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
installResult.append(separator)
|
||||
installResult.append(
|
||||
getString(
|
||||
R.string.install_game_content_failed_count,
|
||||
errorTotal
|
||||
R.string.install_game_content_failed_count, errorTotal
|
||||
)
|
||||
)
|
||||
installResult.append(separator)
|
||||
|
@ -666,9 +582,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
}
|
||||
|
||||
ProgressDialogFragment.newInstance(
|
||||
this,
|
||||
R.string.exporting_user_data,
|
||||
true
|
||||
this, R.string.exporting_user_data, true
|
||||
) { progressCallback, _ ->
|
||||
val zipResult = FileUtil.zipFromInternalStorage(
|
||||
File(DirectoryInitialization.userDirectory!!),
|
||||
|
@ -692,8 +606,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
}
|
||||
|
||||
ProgressDialogFragment.newInstance(
|
||||
this,
|
||||
R.string.importing_user_data
|
||||
this, R.string.importing_user_data
|
||||
) { progressCallback, _ ->
|
||||
val checkStream =
|
||||
ZipInputStream(BufferedInputStream(contentResolver.openInputStream(result)))
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "core/hle/service/set/system_settings_server.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "frontend_common/config.h"
|
||||
#include "frontend_common/firmware_manager.h"
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
|
@ -283,6 +284,7 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string
|
|||
: Service::AM::LaunchType::ApplicationInitiated,
|
||||
.program_index = static_cast<s32>(program_index),
|
||||
};
|
||||
|
||||
m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath, params);
|
||||
if (m_load_result != Core::SystemResultStatus::Success) {
|
||||
return m_load_result;
|
||||
|
@ -764,35 +766,19 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCabinetMode(JNIEnv* env, jclass cl
|
|||
}
|
||||
|
||||
bool isFirmwarePresent() {
|
||||
auto bis_system =
|
||||
EmulationSession::GetInstance().System().GetFileSystemController().GetSystemNANDContents();
|
||||
if (!bis_system) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Query an applet to see if it's available
|
||||
auto applet_nca =
|
||||
bis_system->GetEntry(0x010000000000100Dull, FileSys::ContentRecordType::Program);
|
||||
if (!applet_nca) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return FirmwareManager::CheckFirmwarePresence(EmulationSession::GetInstance().System());
|
||||
}
|
||||
|
||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isFirmwareAvailable(JNIEnv* env, jclass clazz) {
|
||||
return isFirmwarePresent();
|
||||
}
|
||||
|
||||
// TODO(crueter): This check is nonfunctional...
|
||||
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_firmwareVersion(JNIEnv* env, jclass clazz) {
|
||||
Service::Set::FirmwareVersionFormat firmware_data{};
|
||||
const auto result = Service::Set::GetFirmwareVersionImpl(
|
||||
firmware_data, EmulationSession::GetInstance().System(),
|
||||
Service::Set::GetFirmwareVersionType::Version2);
|
||||
const auto pair = FirmwareManager::GetFirmwareVersion(EmulationSession::GetInstance().System());
|
||||
const auto firmware_data = pair.first;
|
||||
const auto result = pair.second;
|
||||
|
||||
if (result.IsError() || !isFirmwarePresent()) {
|
||||
LOG_INFO(Frontend, "Installed firmware: No firmware available");
|
||||
|
||||
return Common::Android::ToJString(env, "N/A");
|
||||
}
|
||||
|
||||
|
@ -804,6 +790,23 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_firmwareVersion(JNIEnv* env, jclas
|
|||
return Common::Android::ToJString(env, display_version);
|
||||
}
|
||||
|
||||
jint Java_org_yuzu_yuzu_1emu_NativeLibrary_verifyFirmware(JNIEnv* env, jclass clazz) {
|
||||
return static_cast<int>(FirmwareManager::VerifyFirmware(EmulationSession::GetInstance().System()));
|
||||
}
|
||||
|
||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_gameRequiresFirmware(JNIEnv* env, jclass clazz, jstring jprogramId) {
|
||||
auto program_id = EmulationSession::GetProgramId(env, jprogramId);
|
||||
|
||||
return FirmwareManager::GameRequiresFirmware(program_id);
|
||||
}
|
||||
|
||||
jint Java_org_yuzu_yuzu_1emu_NativeLibrary_installKeys(JNIEnv* env, jclass clazz, jstring jpath, jstring jext) {
|
||||
const auto path = Common::Android::GetJString(env, jpath);
|
||||
const auto ext = Common::Android::GetJString(env, jext);
|
||||
|
||||
return static_cast<int>(FirmwareManager::InstallKeys(path, ext));
|
||||
}
|
||||
|
||||
jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPatchesForFile(JNIEnv* env, jobject jobj,
|
||||
jstring jpath,
|
||||
jstring jprogramId) {
|
||||
|
|
|
@ -349,13 +349,7 @@
|
|||
<string name="warning_cancel">إلغاء</string>
|
||||
<string name="install_amiibo_keys">تثبيت مفاتيح أميبو</string>
|
||||
<string name="install_amiibo_keys_description">مطلوب لاستخدام أميبو في اللعبة</string>
|
||||
<string name="invalid_keys_file">تم تحديد ملف مفاتيح غير صالح</string>
|
||||
<string name="install_keys_success">تم تثبيت المفاتيح بنجاح</string>
|
||||
<string name="reading_keys_failure">خطأ في قراءة مفاتيح التشفير</string>
|
||||
<string name="install_prod_keys_failure_extension_description">وحاول مرة أخر keys تحقق من أن ملف المفاتيح له امتداد</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">وحاول مرة أخر bin تحقق من أن ملف المفاتيح له امتداد</string>
|
||||
<string name="invalid_keys_error">مفاتيح التشفير غير صالحة</string>
|
||||
<string name="install_keys_failure_description">الملف المحدد غير صحيح أو تالف. يرجى إعادة المفاتيح الخاصة بك</string>
|
||||
<string name="gpu_driver_manager">GPU مدير برنامج تشغيل</string>
|
||||
<string name="install_gpu_driver">GPU تثبيت برنامج تشغيل</string>
|
||||
<string name="install_gpu_driver_description">قم بتثبيت برامج تشغيل بديلة للحصول على أداء أو دقة أفضل</string>
|
||||
|
@ -422,8 +416,6 @@
|
|||
<string name="verify_installed_content_description">فحص المحتوى المثبت بحثًا عن تلف</string>
|
||||
<string name="keys_missing">مفاتيح التشفير مفقودة</string>
|
||||
<string name="keys_missing_description">لا يمكن فك تشفير البرنامج الثابت والألعاب</string>
|
||||
<string name="firmware_missing">البرنامج الثابت مفقود أو جديد جدًا</string>
|
||||
<string name="firmware_missing_description">بعض الألعاب قد لا تعمل بشكل صحيح. يتطلب إيدن البرنامج الثابت 19.0.1 أو أقل.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -344,13 +344,7 @@
|
|||
<string name="warning_cancel">ڕەتکردنەوە</string>
|
||||
<string name="install_amiibo_keys">دامەزراندنی کلیلی Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">پێویستە بۆ بەکارهێنانی Amiibo لە یاریدا</string>
|
||||
<string name="invalid_keys_file">فایلی کلیلێکی نادروست هەڵبژێردرا</string>
|
||||
<string name="install_keys_success">کلیلەکان بە سەرکەوتوویی دامەزران</string>
|
||||
<string name="reading_keys_failure">هەڵە لە خوێندنەوەی کۆدکردنی کلیل</string>
|
||||
<string name="install_prod_keys_failure_extension_description">دڵنیابەوە کە فایلی کلیلەکانت درێژکراوەی .keys ی هەیە و دووبارە هەوڵبدەرەوە.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">دڵنیابە کە فایلی کلیلەکانت درێژکراوەی .bin ی هەیە و دووبارە هەوڵبدەرەوە.</string>
|
||||
<string name="invalid_keys_error">کلیلی کۆدکردنی نادروستە</string>
|
||||
<string name="install_keys_failure_description">فایلە هەڵبژێردراوەکە هەڵەیە یان تێکچووە. تکایە دووبارە کلیلەکانت دەربێنەوە.</string>
|
||||
<string name="install_gpu_driver">دامەزراندنی وەگەڕخەری GPU</string>
|
||||
<string name="install_gpu_driver_description">دامەزراندنی وەگەڕخەری بەدیل بۆ ئەوەی بە ئەگەرێکی زۆرەوە کارایی باشتر یان وردبینی هەبێت</string>
|
||||
<string name="advanced_settings">ڕێکخستنە پێشکەوتووەکان</string>
|
||||
|
@ -416,8 +410,6 @@
|
|||
<string name="verify_installed_content_description">هەموو ناوەڕۆکی دامەزراو پشکنین دەکات بۆ تێکچوون</string>
|
||||
<string name="keys_missing">کلیلە کۆدکراوەکان دیار نییە</string>
|
||||
<string name="keys_missing_description">پتەوواڵا و یارییە تاکەکەسییەکان ناتوانرێت کۆد بکرێنەوە</string>
|
||||
<string name="firmware_missing">فریموێر بوونی نییە یان زۆر نوێە</string>
|
||||
<string name="firmware_missing_description">هەندێ یاری لەوانەیە باش کار نەکەن. ئێدەن پێویستی بە فریموێری ١٩.٠.١ یان کەمترە.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -333,10 +333,6 @@
|
|||
<string name="warning_cancel">Zrušit</string>
|
||||
<string name="install_amiibo_keys">Instalovat Amiibo klíče</string>
|
||||
<string name="install_amiibo_keys_description">Povinné použití Amiibo ve hře</string>
|
||||
<string name="invalid_keys_file">Vybrané klíče jsou neplatné</string>
|
||||
<string name="install_keys_success">Klíče úspěšně nainstalovány</string>
|
||||
<string name="reading_keys_failure">Chyba při čtení šifrovacích klíčů</string>
|
||||
<string name="invalid_keys_error">Neplatné šifrovací klíče</string>
|
||||
<string name="gpu_driver_manager">Správce ovladače GPU</string>
|
||||
<string name="install_gpu_driver">Instalovat GPU ovladač</string>
|
||||
<string name="advanced_settings">Pokročilé nastavení</string>
|
||||
|
@ -380,8 +376,6 @@
|
|||
<string name="verify_installed_content_description">Kontrola poškození obsahu</string>
|
||||
<string name="keys_missing">Chybí šifrovací klíče</string>
|
||||
<string name="keys_missing_description">Firmware a retail hry nelze dešifrovat</string>
|
||||
<string name="firmware_missing">Firmware chybí nebo je příliš nový</string>
|
||||
<string name="firmware_missing_description">Některé hry nemusí fungovat správně. Eden vyžaduje firmware 19.0.1 nebo nižší.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -346,13 +346,7 @@
|
|||
<string name="warning_cancel">Abbrechen</string>
|
||||
<string name="install_amiibo_keys">Amiibo-Schlüssel installieren</string>
|
||||
<string name="install_amiibo_keys_description">Benötigt um Amiibos im Spiel zu verwenden</string>
|
||||
<string name="invalid_keys_file">Ungültige Schlüsseldatei ausgewählt</string>
|
||||
<string name="install_keys_success">Schlüssel erfolgreich installiert</string>
|
||||
<string name="reading_keys_failure">Fehler beim Lesen der Schlüssel</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Überprüfen Sie, ob Ihre Schlüsseldatei die Erweiterung \".keys\" hat, und versuchen Sie es erneut.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Überprüfen Sie, ob Ihre Schlüsseldatei die Erweiterung \".bin\" hat, und versuchen Sie es erneut.</string>
|
||||
<string name="invalid_keys_error">Ungültige Schlüssel</string>
|
||||
<string name="install_keys_failure_description">Die ausgewählte Datei ist falsch oder beschädigt. Bitte kopieren Sie Ihre Schlüssel erneut.</string>
|
||||
<string name="gpu_driver_manager">GPU-Treiber Verwaltung</string>
|
||||
<string name="install_gpu_driver">GPU-Treiber installieren</string>
|
||||
<string name="install_gpu_driver_description">Alternative Treiber für eventuell bessere Leistung oder Genauigkeit installieren</string>
|
||||
|
@ -415,8 +409,6 @@ Wirklich fortfahren?</string>
|
|||
<string name="verify_installed_content_description">Überprüft installierte Inhalte auf Fehler</string>
|
||||
<string name="keys_missing">Schlüssel fehlen</string>
|
||||
<string name="keys_missing_description">Firmware und Spiele können nicht entschlüsselt werden</string>
|
||||
<string name="firmware_missing">Firmware fehlt oder ist zu neu</string>
|
||||
<string name="firmware_missing_description">Einige Spiele funktionieren möglicherweise nicht richtig. Eden erfordert Firmware 19.0.1 oder älter.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -347,13 +347,7 @@
|
|||
<string name="warning_cancel">Cancelar</string>
|
||||
<string name="install_amiibo_keys">Instalar claves de Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Necesario para usar Amiibos en el juego</string>
|
||||
<string name="invalid_keys_file">Archivo de claves seleccionado no válido</string>
|
||||
<string name="install_keys_success">Claves instaladas correctamente</string>
|
||||
<string name="reading_keys_failure">Error al leer las claves de cifrado</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Compruebe que el archivo de claves tenga una extensión .keys y pruebe otra vez.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Compruebe que el archivo de claves tenga una extensión .bin y pruebe otra vez.</string>
|
||||
<string name="invalid_keys_error">Claves de cifrado no válidas</string>
|
||||
<string name="install_keys_failure_description">El archivo seleccionado es incorrecto o está corrupto. Vuelva a redumpear sus claves.</string>
|
||||
<string name="gpu_driver_manager">Explorador de drivers de GPU</string>
|
||||
<string name="install_gpu_driver">Instalar driver de GPU</string>
|
||||
<string name="install_gpu_driver_description">Instale drivers alternativos para obtener un rendimiento o una precisión potencialmente mejores</string>
|
||||
|
@ -428,8 +422,6 @@
|
|||
<string name="verify_installed_content_description">Comprueba todo el contenido instalado por si hubiese alguno corrupto</string>
|
||||
<string name="keys_missing">Faltan las claves de encriptación</string>
|
||||
<string name="keys_missing_description">El firmware y los juegos no se pueden desencriptar</string>
|
||||
<string name="firmware_missing">Falta el firmware o es demasiado nuevo</string>
|
||||
<string name="firmware_missing_description">Algunos juegos pueden no funcionar correctamente. Eden requiere firmware 19.0.1 o inferior.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -347,13 +347,7 @@
|
|||
<string name="warning_cancel">لغو</string>
|
||||
<string name="install_amiibo_keys">کلیدهای Amiibo را نصب کنید</string>
|
||||
<string name="install_amiibo_keys_description">برای استفاده از Amiibo در بازی لازم است</string>
|
||||
<string name="invalid_keys_file">فایل کلیدهای نامعتبر انتخاب شد</string>
|
||||
<string name="install_keys_success">کلیدها با موفقیت نصب شدند</string>
|
||||
<string name="reading_keys_failure">خطا در خواندن کلیدهای رمزگذاری</string>
|
||||
<string name="install_prod_keys_failure_extension_description">بررسی کنید که فایل کلیدهای شما دارای پسوند keys. باشد و دوباره امتحان کنید.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">بررسی کنید که فایل کلیدهای شما دارای پسوند bin. باشد و دوباره امتحان کنید.</string>
|
||||
<string name="invalid_keys_error">کلیدهای رمزگذاری نامعتبر</string>
|
||||
<string name="install_keys_failure_description">فایل انتخابی نادرست یا خراب است. لطفا کلیدهای خود را دوباره استخراج کنید.</string>
|
||||
<string name="gpu_driver_manager">مدیریت درایور پردازنده گرافیکی</string>
|
||||
<string name="install_gpu_driver">نصب درایور پردازنده گرافیکی</string>
|
||||
<string name="install_gpu_driver_description">درایورهای جایگزین را برای عملکرد یا دقت بهتر نصب کنید</string>
|
||||
|
@ -426,8 +420,6 @@
|
|||
<string name="verify_installed_content_description">تمام محتوای نصب شده را از نظر خرابی بررسی میکند</string>
|
||||
<string name="keys_missing">کلیدهای رمزگذاری وجود ندارند</string>
|
||||
<string name="keys_missing_description">ثابتافزار و بازیهای فروشگاهی قابل رمزگشایی نیستند</string>
|
||||
<string name="firmware_missing">فریمور وجود ندارد یا خیلی جدید است</string>
|
||||
<string name="firmware_missing_description">برخی بازیها ممکن است به درستی کار نکنند. ایدن به فریمور نسخه 19.0.1 یا پایینتر نیاز دارد.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -347,13 +347,7 @@
|
|||
<string name="warning_cancel">Annuler</string>
|
||||
<string name="install_amiibo_keys">Installer les clés Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Nécessaire pour utiliser les Amiibo en jeu</string>
|
||||
<string name="invalid_keys_file">Fichier de clés sélectionné invalide</string>
|
||||
<string name="install_keys_success">Clés installées avec succès</string>
|
||||
<string name="reading_keys_failure">Erreur lors de la lecture des clés de chiffrement</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Vérifiez que votre fichier de clés a une extension .keys et réessayez.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Vérifiez que votre fichier de clés a une extension .bin et réessayez.</string>
|
||||
<string name="invalid_keys_error">Clés de chiffrement invalides</string>
|
||||
<string name="install_keys_failure_description">Le fichier sélectionné est incorrect ou corrompu. Veuillez dumper à nouveau vos clés.</string>
|
||||
<string name="gpu_driver_manager">Gestionnaire de pilotes du GPU</string>
|
||||
<string name="install_gpu_driver">Installer le pilote du GPU</string>
|
||||
<string name="install_gpu_driver_description">Installer des pilotes alternatifs pour des performances ou une précision potentiellement meilleures</string>
|
||||
|
@ -428,8 +422,6 @@
|
|||
<string name="verify_installed_content_description">Vérifie l\'intégrité des contenus installés</string>
|
||||
<string name="keys_missing">Les clés de chiffrement sont manquantes.</string>
|
||||
<string name="keys_missing_description">Le firmware et les jeux commerciaux ne peuvent pas être déchiffrés</string>
|
||||
<string name="firmware_missing">Firmware manquant ou trop récent</string>
|
||||
<string name="firmware_missing_description">Certains jeux peuvent ne pas fonctionner correctement. Eden nécessite le firmware 19.0.1 ou antérieur.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -348,13 +348,7 @@
|
|||
<string name="warning_cancel">ביטול</string>
|
||||
<string name="install_amiibo_keys">התקן מפתחות Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">נחוץ כדי להשתמש ב Amiibo במשחק</string>
|
||||
<string name="invalid_keys_file">קובץ מפתחות לא חוקי נבחר</string>
|
||||
<string name="install_keys_success">מפתחות הותקנו בהצלחה</string>
|
||||
<string name="reading_keys_failure">שגיאה בקריאת מפתחות ההצפנה</string>
|
||||
<string name="install_prod_keys_failure_extension_description">ודא שלקובץ המפתחות שלך יש סיומת של key. ונסה/י שוב.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">ודא/י שלקובץ המפתחות שלך יש סיומת של bin. ונסה/י שוב.</string>
|
||||
<string name="invalid_keys_error">מפתחות הצפנה לא חוקיים</string>
|
||||
<string name="install_keys_failure_description">קבוץ שנבחר מושחת או לא נכון. בבקשה הוצא מחדש את המפתחות שלך.</string>
|
||||
<string name="gpu_driver_manager">מנהל הדרייברים של המעבד הגרפי</string>
|
||||
<string name="install_gpu_driver">התקן דרייבר למעבד הגרפי</string>
|
||||
<string name="install_gpu_driver_description">התקן דרייברים אחרים בשביל סיכוי לביצועים או דיוק גבוההים יותר</string>
|
||||
|
@ -427,8 +421,6 @@
|
|||
<string name="verify_installed_content_description">בודק תוכן מותקן לשגיאות</string>
|
||||
<string name="keys_missing">מפתחות הצפנה חסרים</string>
|
||||
<string name="keys_missing_description">לא ניתן לפענח firmware ומשחקים</string>
|
||||
<string name="firmware_missing">קושחה חסרה או חדשה מדי</string>
|
||||
<string name="firmware_missing_description">חלק מהמשחקים עשויים לא לפעול כראוי. Eden דורש קושחה בגרסה 19.0.1 או נמוכה יותר.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -346,13 +346,7 @@
|
|||
<string name="warning_cancel">Mégse</string>
|
||||
<string name="install_amiibo_keys">Amiibo kulcsok telepítése</string>
|
||||
<string name="install_amiibo_keys_description">Amiibo használata szükséges a játékhoz</string>
|
||||
<string name="invalid_keys_file">Érvénytelen titkosítófájlok kiválasztva</string>
|
||||
<string name="install_keys_success">Kulcsok sikeresen telepítve</string>
|
||||
<string name="reading_keys_failure">Hiba történt a titkosítókulcsok olvasása során</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Győződj meg róla, hogy a titkosító fájlod .keys kiterjesztéssel rendelkezik, majd próbáld újra.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Győződj meg róla, hogy a titkosító fájlod .bin kiterjesztéssel rendelkezik, majd próbáld újra.</string>
|
||||
<string name="invalid_keys_error">Érvénytelen titkosítókulcsok</string>
|
||||
<string name="install_keys_failure_description">A kiválasztott fájl helytelen, vagy sérült. Állíts össze egy új kulcsot.</string>
|
||||
<string name="gpu_driver_manager">GPU illesztőprogram-kezelő</string>
|
||||
<string name="install_gpu_driver">GPU illesztőprogram telepítése</string>
|
||||
<string name="install_gpu_driver_description">Alternatív illesztőprogramok telepítése az esetlegesen elérhető teljesítmény és pontosság érdekében</string>
|
||||
|
@ -424,8 +418,6 @@
|
|||
<string name="verify_installed_content_description">A telepített tartalom épségét ellenőrzi</string>
|
||||
<string name="keys_missing">Hiányzó titkosítókulcsok</string>
|
||||
<string name="keys_missing_description">A Firmware és a kiskereskedelmi (retail) játékok nem dekódolhatók</string>
|
||||
<string name="firmware_missing">Hiányzó vagy túl új firmware</string>
|
||||
<string name="firmware_missing_description">Néhány játék nem fog megfelelően működni. Az Eden 19.0.1 vagy régebbi firmware-t igényel.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -347,13 +347,7 @@
|
|||
<string name="warning_cancel">Batalkan</string>
|
||||
<string name="install_amiibo_keys">Install Amiibo keys</string>
|
||||
<string name="install_amiibo_keys_description">Diperlukan untuk menggunakan Amiibo di dalam game</string>
|
||||
<string name="invalid_keys_file">Keys yang dipilih invalid</string>
|
||||
<string name="install_keys_success">Keys berhasil diinstal</string>
|
||||
<string name="reading_keys_failure">Error saat mengecek enkripsi keys</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Pastikan file keys anda memiliki format .keys dan coba lagi.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Pastikan file keys anda memiliki format .bin dan coba lagi.</string>
|
||||
<string name="invalid_keys_error">Keys enkripsi tidak valid</string>
|
||||
<string name="install_keys_failure_description">File yang dipilih salah atau rusak. Silakan masukkan kembali kunci Anda.</string>
|
||||
<string name="gpu_driver_manager">Manajer driver GPU</string>
|
||||
<string name="install_gpu_driver">Install driver GPU</string>
|
||||
<string name="install_gpu_driver_description">Instal driver lain untuk kinerja atau akurasi yang berpotensi lebih baik</string>
|
||||
|
@ -424,8 +418,6 @@
|
|||
<string name="verify_installed_content_description">Memeriksa semua konten yang terinstal dari kerusakan</string>
|
||||
<string name="keys_missing">Kunci enkripsi hilang</string>
|
||||
<string name="keys_missing_description">Firmware dan game retail tidak dapat didekripsi</string>
|
||||
<string name="firmware_missing">Firmware hilang atau terlalu baru</string>
|
||||
<string name="firmware_missing_description">Beberapa game mungkin tidak berfungsi dengan baik. Eden memerlukan firmware 19.0.1 atau lebih rendah.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -348,13 +348,7 @@
|
|||
<string name="warning_cancel">Annulla</string>
|
||||
<string name="install_amiibo_keys">Installa le chiavi degli Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Necessario per usare gli Amiibo in gioco</string>
|
||||
<string name="invalid_keys_file">Selezionate chiavi non valide</string>
|
||||
<string name="install_keys_success">Chiavi installate correttamente</string>
|
||||
<string name="reading_keys_failure">Errore durante la lettura delle chiavi di crittografia</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Controlla che le tue chiavi abbiano l\'estensione .keys e prova di nuovo.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Controlla che le tue chiavi abbiano l\'estensione .bin e prova di nuovo</string>
|
||||
<string name="invalid_keys_error">Chiavi di crittografia non valide</string>
|
||||
<string name="install_keys_failure_description">Il file selezionato è incorretto o corrotto. Per favore riesegui il dump delle tue chiavi.</string>
|
||||
<string name="gpu_driver_manager">Gestore driver GPU</string>
|
||||
<string name="install_gpu_driver">Installa i driver GPU</string>
|
||||
<string name="install_gpu_driver_description">Installa driver alternativi per potenziali prestazioni migliori o accuratezza.</string>
|
||||
|
@ -427,8 +421,6 @@
|
|||
<string name="verify_installed_content_description">Verifica l\'integrità di tutti i contenuti installati.</string>
|
||||
<string name="keys_missing">Chiavi di crittografia mancanti</string>
|
||||
<string name="keys_missing_description">Impossibile decifrare firmware e giochi retail</string>
|
||||
<string name="firmware_missing">Firmware mancante o troppo recente</string>
|
||||
<string name="firmware_missing_description">Alcuni giochi potrebbero non funzionare correttamente. Eden richiede il firmware 19.0.1 o precedente.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -346,13 +346,7 @@
|
|||
<string name="warning_cancel">キャンセル</string>
|
||||
<string name="install_amiibo_keys">Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">ゲーム内での Amiibo の使用に必要です</string>
|
||||
<string name="invalid_keys_file">無効なキーファイルです</string>
|
||||
<string name="install_keys_success">正常にインストールされました</string>
|
||||
<string name="reading_keys_failure">暗号化キーの読み込み失敗</string>
|
||||
<string name="install_prod_keys_failure_extension_description">キーの拡張子が.keysであることを確認し、再度お試しください。</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">キーの拡張子が.binであることを確認し、再度お試しください。</string>
|
||||
<string name="invalid_keys_error">暗号化キーが無効</string>
|
||||
<string name="install_keys_failure_description">ファイルが間違っているか破損しています。キーを再ダンプしてください。</string>
|
||||
<string name="gpu_driver_manager">GPUドライバーの管理</string>
|
||||
<string name="install_gpu_driver">GPUドライバー</string>
|
||||
<string name="install_gpu_driver_description">代替ドライバーをインストールしてパフォーマンスや精度を向上させます</string>
|
||||
|
@ -417,8 +411,6 @@
|
|||
<string name="verify_installed_content_description">すべてのインストール済みコンテンツの整合性を確認</string>
|
||||
<string name="keys_missing">暗号化キーが不足</string>
|
||||
<string name="keys_missing_description">ファームウェアと製品版ゲームを復号化できません</string>
|
||||
<string name="firmware_missing">ファームウェアがないか、バージョンが新しすぎます</string>
|
||||
<string name="firmware_missing_description">一部のゲームが正常に動作しない可能性があります。Edenは19.0.1以下のファームウェアが必要です。</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -346,13 +346,7 @@
|
|||
<string name="warning_cancel">취소</string>
|
||||
<string name="install_amiibo_keys">amiibo 키 설치</string>
|
||||
<string name="install_amiibo_keys_description">게임에서 amiibo 사용 시 필요</string>
|
||||
<string name="invalid_keys_file">잘못된 키 파일이 선택됨</string>
|
||||
<string name="install_keys_success">키 값을 설치했습니다.</string>
|
||||
<string name="reading_keys_failure">암호화 키 읽기 오류</string>
|
||||
<string name="install_prod_keys_failure_extension_description">키 파일의 확장자가 .keys인지 확인하고 다시 시도하세요.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">키 파일의 확장자가 .bin인지 확인하고 다시 시도하세요.</string>
|
||||
<string name="invalid_keys_error">암호화 키가 올바르지 않음</string>
|
||||
<string name="install_keys_failure_description">선택한 파일이 잘못되었거나 손상되었습니다. 키를 다시 덤프하세요.</string>
|
||||
<string name="gpu_driver_manager">GPU 드라이버 관리자</string>
|
||||
<string name="install_gpu_driver">GPU 드라이버 설치</string>
|
||||
<string name="install_gpu_driver_description">잠재적인 성능 또는 정확도 개선을 위해 대체 드라이버 설치</string>
|
||||
|
@ -423,8 +417,6 @@
|
|||
<string name="verify_installed_content_description">전체 설치된 콘텐츠의 손상을 확인합니다.</string>
|
||||
<string name="keys_missing">암호화 키를 찾을 수 없음</string>
|
||||
<string name="keys_missing_description">펌웨어 및 패키지 게임을 해독할 수 없음</string>
|
||||
<string name="firmware_missing">펌웨어가 없거나 버전이 너무 높습니다</string>
|
||||
<string name="firmware_missing_description">일부 게임이 제대로 작동하지 않을 수 있습니다. Eden은 19.0.1 이하 버전의 펌웨어가 필요합니다.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -344,13 +344,7 @@
|
|||
<string name="warning_cancel">Avbryt</string>
|
||||
<string name="install_amiibo_keys">Installer Amiibo-nøkler</string>
|
||||
<string name="install_amiibo_keys_description">Kreves for å bruke Amiibo i spillet</string>
|
||||
<string name="invalid_keys_file">Ugyldig nøkkelfil valgt</string>
|
||||
<string name="install_keys_success">Nøkler vellykket installert</string>
|
||||
<string name="reading_keys_failure">Feil ved lesing av krypteringsnøkler</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Kontroller at nøkkelfilen har filtypen .keys, og prøv igjen.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Kontroller at nøkkelfilen har filtypen .bin, og prøv igjen.</string>
|
||||
<string name="invalid_keys_error">Ugyldige krypteringsnøkler</string>
|
||||
<string name="install_keys_failure_description">Den valgte filen er feil eller ødelagt. Vennligst dump nøklene på nytt.</string>
|
||||
<string name="install_gpu_driver">Installer GPU-driver</string>
|
||||
<string name="install_gpu_driver_description">Installer alternative drivere for potensielt bedre ytelse eller nøyaktighet.</string>
|
||||
<string name="advanced_settings">Avanserte innstillinger</string>
|
||||
|
@ -416,8 +410,6 @@
|
|||
<string name="verify_installed_content_description">Sjekk for korrupsjon</string>
|
||||
<string name="keys_missing">Nøkler mangler</string>
|
||||
<string name="keys_missing_description">Kan ikke dekryptere firmware/spill</string>
|
||||
<string name="firmware_missing">Firmware mangler eller er for ny</string>
|
||||
<string name="firmware_missing_description">Noen spill fungerer kanskje ikke skikkelig. Eden krever firmware 19.0.1 eller lavere.</string>
|
||||
|
||||
<!-- Applet-lanseringsstrenger -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -344,13 +344,7 @@
|
|||
<string name="warning_cancel">Anuluj</string>
|
||||
<string name="install_amiibo_keys">Zainstaluj klucze Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Wymagane aby korzystać z Amiibo w grze</string>
|
||||
<string name="invalid_keys_file">Wybrano niepoprawne klucze</string>
|
||||
<string name="install_keys_success">Klucze zainstalowane pomyślnie</string>
|
||||
<string name="reading_keys_failure">Błąd podczas odczytu kluczy</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Upewnij się że twoje klucze mają rozszerzenie .keys i spróbuj ponownie.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Upewnij się że twoje klucze mają rozszerzenie .bin i spróbuj ponownie.</string>
|
||||
<string name="invalid_keys_error">Niepoprawne klucze</string>
|
||||
<string name="install_keys_failure_description">Wybrany plik jest niepoprawny lub uszkodzony. Zrzuć ponownie swoje klucze.</string>
|
||||
<string name="install_gpu_driver">Zainstaluj sterownik GPU</string>
|
||||
<string name="install_gpu_driver_description">Użyj alternatywnych sterowników aby potencjalnie zwiększyć wydajność i naprawić błędy</string>
|
||||
<string name="advanced_settings">Ustawienia zaawansowane</string>
|
||||
|
@ -416,8 +410,6 @@
|
|||
<string name="verify_installed_content_description">Sprawdza integralność zainstalowanych plików.</string>
|
||||
<string name="keys_missing">Brak kluczy</string>
|
||||
<string name="keys_missing_description">Firmware i gry nie mogą być odszyfrowane.</string>
|
||||
<string name="firmware_missing">Brak firmware lub zbyt nowa wersja</string>
|
||||
<string name="firmware_missing_description">Niektóre gry mogą nie działać poprawnie. Eden wymaga firmware w wersji 19.0.1 lub starszej.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -347,13 +347,7 @@
|
|||
<string name="warning_cancel">Cancelar</string>
|
||||
<string name="install_amiibo_keys">Instalar chaves Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Necessárias para usar Amiibos em um jogo</string>
|
||||
<string name="invalid_keys_file">Arquivo de chaves selecionado inválido</string>
|
||||
<string name="install_keys_success">Chaves instaladas com sucesso</string>
|
||||
<string name="reading_keys_failure">Erro ao ler chaves de encriptação</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Verifique se seu arquivo de chaves possui a extensão .keys e tente novamente.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Verifique se seu arquivo de chaves possui a extensão .bin e tente novamente.</string>
|
||||
<string name="invalid_keys_error">Chaves de encriptação inválidas</string>
|
||||
<string name="install_keys_failure_description">O arquivo selecionado está incorreto ou corrompido. Por favor extraia suas chaves novamente.</string>
|
||||
<string name="gpu_driver_manager">Gerenciador de driver de GPU</string>
|
||||
<string name="install_gpu_driver">Instalar driver para GPU</string>
|
||||
<string name="install_gpu_driver_description">Instale drivers alternativos para desempenho ou precisão potencialmente melhores</string>
|
||||
|
@ -428,8 +422,6 @@
|
|||
<string name="verify_installed_content_description">Verifica todo o conteúdo instalado em busca de dados corrompidos</string>
|
||||
<string name="keys_missing">Faltando chaves de encriptação</string>
|
||||
<string name="keys_missing_description">O firmware e jogos comerciais não poderão ser decriptados</string>
|
||||
<string name="firmware_missing">Firmware ausente ou muito recente</string>
|
||||
<string name="firmware_missing_description">Alguns jogos podem não funcionar corretamente. O Eden requer firmware 19.0.1 ou inferior.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -347,13 +347,7 @@
|
|||
<string name="warning_cancel">Cancelar</string>
|
||||
<string name="install_amiibo_keys">Instala chaves Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Necessário para usares Amiibo no jogo</string>
|
||||
<string name="invalid_keys_file">Ficheiro de chaves inválido</string>
|
||||
<string name="install_keys_success">Chaves instaladas com sucesso</string>
|
||||
<string name="reading_keys_failure">Erro ao ler chaves de encriptação</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Verifique se seu arquivo keys possui a extensão .keys e tente novamente.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Verifique se seu arquivo keys possui a extensão .bin e tente novamente.</string>
|
||||
<string name="invalid_keys_error">Chaves de encriptação inválidas</string>
|
||||
<string name="install_keys_failure_description">O ficheiro selecionado está corrompido. Por favor recarrega as tuas chaves.</string>
|
||||
<string name="gpu_driver_manager">Gerenciador de driver de GPU</string>
|
||||
<string name="install_gpu_driver">Instala driver para GPU</string>
|
||||
<string name="install_gpu_driver_description">Instala drivers alternativos para desempenho ou precisão potencialmente melhores</string>
|
||||
|
@ -428,8 +422,6 @@
|
|||
<string name="verify_installed_content_description">Verifica todo o conteúdo instalado em busca de dados corrompidos</string>
|
||||
<string name="keys_missing">Faltando chaves de encriptação</string>
|
||||
<string name="keys_missing_description">O firmware e jogos comerciais não poderão ser decriptados</string>
|
||||
<string name="firmware_missing">Firmware em falta ou demasiado recente</string>
|
||||
<string name="firmware_missing_description">Alguns jogos podem não funcionar corretamente. O Eden requer firmware versão 19.0.1 ou inferior.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -346,13 +346,7 @@
|
|||
<string name="warning_cancel">Отмена</string>
|
||||
<string name="install_amiibo_keys">Установить ключи Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Необходимо для использования Amiibo в играх</string>
|
||||
<string name="invalid_keys_file">Выбран неверный файл ключей</string>
|
||||
<string name="install_keys_success">Ключи успешно установлены</string>
|
||||
<string name="reading_keys_failure">Ошибка при чтении ключей шифрования</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Убедитесь, что файл ключей имеет расширение .keys, и повторите попытку.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Убедитесь, что файл ключей имеет расширение .bin, и повторите попытку.</string>
|
||||
<string name="invalid_keys_error">Неверные ключи шифрования</string>
|
||||
<string name="install_keys_failure_description">Выбранный файл неверен или поврежден. Пожалуйста, пере-дампите ваши ключи.</string>
|
||||
<string name="gpu_driver_manager">Менеджер драйверов ГП</string>
|
||||
<string name="install_gpu_driver">Установить драйвер ГП</string>
|
||||
<string name="install_gpu_driver_description">Установите альтернативные драйверы для потенциально лучшей производительности и/или точности</string>
|
||||
|
@ -430,8 +424,6 @@
|
|||
<string name="verify_installed_content_description">Проверяет весь установленный контент на наличие повреждений</string>
|
||||
<string name="keys_missing">Отсутствуют ключи шифрования</string>
|
||||
<string name="keys_missing_description">Прошивка и розничные игры не могут быть расшифрованы</string>
|
||||
<string name="firmware_missing">Прошивка отсутствует или слишком новая</string>
|
||||
<string name="firmware_missing_description">Некоторые игры могут работать некорректно. Eden требует прошивку версии 19.0.1 или ниже.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -298,13 +298,7 @@
|
|||
<string name="warning_cancel">Отказати</string>
|
||||
<string name="install_amiibo_keys">Инсталирајте Амиибо Кеис</string>
|
||||
<string name="install_amiibo_keys_description">Потребно је користити Амиибо у игри</string>
|
||||
<string name="invalid_keys_file">Изабрана је неважећа датотека тастера</string>
|
||||
<string name="install_keys_success">Кључеви су успешно инсталирани</string>
|
||||
<string name="reading_keys_failure">Грешка приликом чишћења кључева за шифровање</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Проверите да датотека кључева има. Екеис Ектенсион и покушајте поново.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Проверите да датотека кључева има .бин екстензију и покушајте поново.</string>
|
||||
<string name="invalid_keys_error">Неважеће кључеве за шифровање</string>
|
||||
<string name="install_keys_failure_description">Изабрана датотека је нетачна или оштећена. Молим вас да вам умањите кључеве.</string>
|
||||
<string name="gpu_driver_fetcher">ГПУ возач фетцхер</string>
|
||||
<string name="gpu_driver_manager">ГПУ управљач возача</string>
|
||||
<string name="install_gpu_driver">Инсталирајте ГПУ драјвер</string>
|
||||
|
@ -380,8 +374,6 @@
|
|||
<string name="keys_missing">Шифра о шифрирањима недостају</string>
|
||||
<string name="keys_missing_description">Фирмваре и малопродајне игре не могу се дешифровати</string>
|
||||
|
||||
<string name="firmware_missing">Фирмвер недостаје или је превише нов</string>
|
||||
<string name="firmware_missing_description">Неке игре можда неће радити исправно. Eden захтева фирмвер верзије 19.0.1 или старији.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Клаунцх</string>
|
||||
|
|
|
@ -344,12 +344,6 @@
|
|||
<string name="warning_cancel">Відміна</string>
|
||||
<string name="install_amiibo_keys">Встановити ключі Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Необхідно для використання Amiibo в іграх</string>
|
||||
<string name="invalid_keys_file">Вибрано неправильний файл ключів</string>
|
||||
<string name="install_keys_success">Ключі успішно встановлено</string>
|
||||
<string name="reading_keys_failure">Помилка під час зчитування ключів шифрування</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Переконайтеся, що файл ключів має розширення .keys, і повторіть спробу.</string>
|
||||
<string name="invalid_keys_error">Невірні ключі шифрування</string>
|
||||
<string name="install_keys_failure_description">Обраний файл невірний або пошкоджений. Будь ласка, зробіть повторний дамп ваших ключів.</string>
|
||||
<string name="install_gpu_driver">Встановити драйвер GPU</string>
|
||||
<string name="install_gpu_driver_description">Встановіть альтернативні драйвери для потенційно кращої продуктивності та/або точності</string>
|
||||
<string name="advanced_settings">Розширені налаштування</string>
|
||||
|
@ -415,8 +409,6 @@
|
|||
<string name="verify_installed_content_description">Перевіряє встановлений вміст на наявність помилок.</string>
|
||||
<string name="keys_missing">Відсутні ключі</string>
|
||||
<string name="keys_missing_description">Прошивку та роздрібні ігри не вдасться розшифрувати.</string>
|
||||
<string name="firmware_missing">Прошивка відсутня або занадто нова</string>
|
||||
<string name="firmware_missing_description">Деякі ігри можуть працювати неправильно. Eden вимагає прошивку версії 19.0.1 або нижче.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -344,13 +344,7 @@
|
|||
<string name="warning_cancel">Huỷ</string>
|
||||
<string name="install_amiibo_keys">Cài đặt Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Cần thiết để dùng Amiibo trong trò chơi</string>
|
||||
<string name="invalid_keys_file">Chìa khóa không hợp lệ</string>
|
||||
<string name="install_keys_success">Cài đặt chìa khóa thành công</string>
|
||||
<string name="reading_keys_failure">Lỗi đọc keys mã hóa</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Xác minh rằng tệp keys của bạn có đuôi .keys và thử lại.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Xác minh rằng tệp keys của bạn có đuôi .bin và thử lại.</string>
|
||||
<string name="invalid_keys_error">Keys mã hoá không hợp lệ</string>
|
||||
<string name="install_keys_failure_description">Chọn file sai hoặc bị hỏng. Hãy xuất chìa khóa khác</string>
|
||||
<string name="install_gpu_driver">Cài đặt driver GPU</string>
|
||||
<string name="install_gpu_driver_description">Cài đặt driver thay thế để có thể có hiệu suất tốt và chính xác hơn</string>
|
||||
<string name="advanced_settings">Cài đặt nâng cao</string>
|
||||
|
@ -416,8 +410,6 @@
|
|||
<string name="verify_installed_content_description">Kiểm tra lỗi nội dung đã cài</string>
|
||||
<string name="keys_missing">Thiếu keys mã hóa</string>
|
||||
<string name="keys_missing_description">Không thể giải mã firmware và game</string>
|
||||
<string name="firmware_missing">Thiếu firmware hoặc phiên bản quá mới</string>
|
||||
<string name="firmware_missing_description">Một số trò chơi có thể không hoạt động bình thường. Eden yêu cầu firmware phiên bản 19.0.1 hoặc thấp hơn.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -346,13 +346,7 @@
|
|||
<string name="warning_cancel">取消</string>
|
||||
<string name="install_amiibo_keys">安装 Amiibo 密钥文件</string>
|
||||
<string name="install_amiibo_keys_description">在遊戏中使用 Amiibo 时必需</string>
|
||||
<string name="invalid_keys_file">选择的密钥文件无效</string>
|
||||
<string name="install_keys_success">密钥文件已成功安装</string>
|
||||
<string name="reading_keys_failure">读取加密密钥时出错</string>
|
||||
<string name="install_prod_keys_failure_extension_description">请确保您的密钥文件扩展名为 .keys 并重试。</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">请确保您的密钥文件扩展名为 .bin 并重试。</string>
|
||||
<string name="invalid_keys_error">无效的加密密钥</string>
|
||||
<string name="install_keys_failure_description">选择的密钥文件不正确或已损坏。请重新转储密钥文件。</string>
|
||||
<string name="gpu_driver_manager">GPU 驱动管理器</string>
|
||||
<string name="install_gpu_driver">安装 GPU 驱动</string>
|
||||
<string name="install_gpu_driver_description">安装替代的驱动程序以获得更好的性能和精度</string>
|
||||
|
@ -423,8 +417,6 @@
|
|||
<string name="verify_installed_content_description">检查所有安装的内容是否有损坏</string>
|
||||
<string name="keys_missing">密钥缺失</string>
|
||||
<string name="keys_missing_description">无法解密固件和商业游戏</string>
|
||||
<string name="firmware_missing">固件缺失或版本过新</string>
|
||||
<string name="firmware_missing_description">某些游戏可能无法正常运行。Eden需要19.0.1或更低版本的固件。</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -350,13 +350,7 @@
|
|||
<string name="warning_cancel">取消</string>
|
||||
<string name="install_amiibo_keys">安裝 Amiibo 金鑰</string>
|
||||
<string name="install_amiibo_keys_description">需要在遊戲中使用 Amiibo</string>
|
||||
<string name="invalid_keys_file">無效的金鑰檔案已選取</string>
|
||||
<string name="install_keys_success">金鑰已成功安裝</string>
|
||||
<string name="reading_keys_failure">讀取加密金鑰時發生錯誤</string>
|
||||
<string name="install_prod_keys_failure_extension_description">驗證您的金鑰檔案是否具有 .keys 副檔名並再試一次。</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">驗證您的金鑰檔案是否具有 .bin 副檔名並再試一次。</string>
|
||||
<string name="invalid_keys_error">無效的加密金鑰</string>
|
||||
<string name="install_keys_failure_description">選取的檔案不正確或已損毀,請重新傾印您的金鑰。</string>
|
||||
<string name="gpu_driver_manager">GPU 驅動程式管理員</string>
|
||||
<string name="install_gpu_driver">安裝 GPU 驅動程式</string>
|
||||
<string name="install_gpu_driver_description">安裝替代驅動程式以取得潛在的更佳效能或準確度</string>
|
||||
|
@ -427,8 +421,6 @@
|
|||
<string name="verify_installed_content_description">检查所有安装的内容是否有损坏</string>
|
||||
<string name="keys_missing">密钥缺失</string>
|
||||
<string name="keys_missing_description">无法解密固件和商业游戏</string>
|
||||
<string name="firmware_missing">韌體缺失或版本過新</string>
|
||||
<string name="firmware_missing_description">某些遊戲可能無法正常運作。Eden需要19.0.1或更低版本的韌體。</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -496,4 +496,18 @@
|
|||
<item>3</item>
|
||||
</integer-array>
|
||||
|
||||
<string-array name="verifyFirmwareResults">
|
||||
<item>""</item>
|
||||
<item>@string/error_firmware_missing</item>
|
||||
<item>@string/error_firmware_corrupted</item>
|
||||
<item>@string/error_firmware_too_new</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="installKeysResults">
|
||||
<item>""</item>
|
||||
<item>""</item>
|
||||
<item>@string/error_keys_copy_failed</item>
|
||||
<item>@string/error_keys_invalid_filename</item>
|
||||
<item>@string/error_keys_failed_init</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
|
|
@ -304,14 +304,8 @@
|
|||
<string name="warning_cancel">Cancel</string>
|
||||
<string name="install_amiibo_keys">Install Amiibo keys</string>
|
||||
<string name="install_amiibo_keys_description">Required to use Amiibo in game</string>
|
||||
<string name="invalid_keys_file">Invalid keys file selected</string>
|
||||
<string name="install_keys_success">Keys successfully installed</string>
|
||||
<string name="reading_keys_failure">Error reading encryption keys</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Verify your keys file has a .keys extension and try again.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Verify your keys file has a .bin extension and try again.</string>
|
||||
<string name="invalid_keys_error">Invalid encryption keys</string>
|
||||
<string name="dumping_keys_quickstart_link">https://yuzu-mirror.github.io/help/quickstart/#dumping-decryption-keys</string>
|
||||
<string name="install_keys_failure_description">The selected file is incorrect or corrupt. Please redump your keys.</string>
|
||||
<string name="gpu_driver_fetcher">GPU driver fetcher</string>
|
||||
<string name="gpu_driver_manager">GPU driver manager</string>
|
||||
<string name="install_gpu_driver">Install GPU driver</string>
|
||||
|
@ -390,10 +384,18 @@
|
|||
<string name="keys_missing_description">Firmware and retail games cannot be decrypted</string>
|
||||
<string name="keys_missing_help">https://yuzu-mirror.github.io/help/quickstart/#dumping-decryption-keys</string>
|
||||
|
||||
<string name="firmware_missing">Firmware is missing or too new</string>
|
||||
<string name="firmware_missing_description">Some games may not function properly. Eden requires firmware 19.0.1 or below.</string>
|
||||
<string name="firmware_invalid">Firmware Invalid</string>
|
||||
<string name="error_firmware_missing">Firmware is required to run certain games and use the Home Menu. Eden only works with firmware 19.0.1 and earlier.</string>
|
||||
<string name="error_firmware_corrupted">Firmware reported as present, but was unable to be read. Check for decryption keys and redump firmware if necessary.</string>
|
||||
<string name="error_firmware_too_new">Firmware is too new or could not be read. Eden only works with firmware 19.0.1 and earlier.</string>
|
||||
<string name="firmware_missing_help">https://yuzu-mirror.github.io/help/quickstart/#dumping-system-firmware</string>
|
||||
|
||||
<string name="keys_failed">Failed to Install Keys</string>
|
||||
<string name="keys_install_success">Keys successfully installed</string>
|
||||
<string name="error_keys_copy_failed">One or more keys failed to copy.</string>
|
||||
<string name="error_keys_invalid_filename">Verify your keys file has a .keys extension and try again.</string>
|
||||
<string name="error_keys_failed_init">Keys failed to initialize. Check that your dumping tools are up to date and re-dump keys.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
<string name="qlaunch_description">Launch applications from the system home screen</string>
|
||||
|
@ -754,13 +756,16 @@
|
|||
|
||||
<!-- ROM loading errors -->
|
||||
<string name="loader_error_encrypted">Your ROM is encrypted</string>
|
||||
<string name="loader_error_encrypted_roms_description"><![CDATA[Please follow the guides to redump your <a href="https://yuzu-mirror.github.io/help/quickstart/#dumping-physical-titles-game-cards">game cartidges</a> or <a href="https://yuzu-mirror.github.io/help/quickstart/#dumping-digital-titles-eshop">installed titles</a>.]]></string>
|
||||
<string name="loader_error_encrypted_roms_description"><![CDATA[Please follow the guides to redump your <a href="https://yuzu-mirror.github.io/help/quickstart/#dumping-physical-titles-game-cards">game cartridges</a> or <a href="https://yuzu-mirror.github.io/help/quickstart/#dumping-digital-titles-eshop">installed titles</a>.]]></string>
|
||||
<string name="loader_error_encrypted_keys_description"><![CDATA[Please ensure your <a href="https://yuzu-mirror.github.io/help/quickstart/#dumping-prodkeys-and-titlekeys">prod.keys</a> file is installed so that games can be decrypted.]]></string>
|
||||
<string name="loader_error_video_core">An error occurred initializing the video core</string>
|
||||
<string name="loader_error_video_core_description">This is usually caused by an incompatible GPU driver. Installing a custom GPU driver may resolve this problem.</string>
|
||||
<string name="loader_error_invalid_format">Unable to load ROM</string>
|
||||
<string name="loader_error_file_not_found">ROM file does not exist</string>
|
||||
|
||||
<string name="loader_requires_firmware">Game Requires Firmware</string>
|
||||
<string name="loader_requires_firmware_description"><![CDATA[The game you are trying to launch requires firmware to boot or to get past the opening menu. Please <a href="https://yuzu-mirror.github.io/help/quickstart"> dump and install firmware</a>, or press "OK" to launch anyways.]]></string>
|
||||
|
||||
<!-- Emulation Menu -->
|
||||
<string name="emulation_exit">Exit emulation</string>
|
||||
<string name="emulation_done">Done</string>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -39,6 +39,9 @@ jclass GetDiskCacheLoadCallbackStageClass();
|
|||
jclass GetGameDirClass();
|
||||
jmethodID GetGameDirConstructor();
|
||||
jmethodID GetDiskCacheLoadProgress();
|
||||
jmethodID GetCopyToStorage();
|
||||
jmethodID GetFileExists();
|
||||
jmethodID GetFileExtension();
|
||||
|
||||
jmethodID GetExitEmulationActivity();
|
||||
jmethodID GetOnEmulationStarted();
|
||||
|
|
|
@ -5,6 +5,8 @@ add_library(frontend_common STATIC
|
|||
config.cpp
|
||||
config.h
|
||||
content_manager.h
|
||||
firmware_manager.h
|
||||
firmware_manager.cpp
|
||||
)
|
||||
|
||||
create_target_directory_groups(frontend_common)
|
||||
|
|
139
src/frontend_common/firmware_manager.cpp
Normal file
139
src/frontend_common/firmware_manager.cpp
Normal file
|
@ -0,0 +1,139 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "firmware_manager.h"
|
||||
#include <filesystem>
|
||||
#include <common/fs/fs_paths.h>
|
||||
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
|
||||
#include "common/logging/backend.h"
|
||||
|
||||
#include "core/crypto/key_manager.h"
|
||||
#include "frontend_common/content_manager.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <jni.h>
|
||||
#include <common/android/id_cache.h>
|
||||
#include <common/android/android_common.h>
|
||||
#endif
|
||||
|
||||
FirmwareManager::KeyInstallResult
|
||||
FirmwareManager::InstallKeys(std::string location, std::string extension) {
|
||||
LOG_INFO(Frontend, "Installing key files from {}", location);
|
||||
|
||||
const auto keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir);
|
||||
|
||||
#ifdef ANDROID
|
||||
JNIEnv *env = Common::Android::GetEnvForThread();
|
||||
|
||||
jstring jsrc = Common::Android::ToJString(env, location);
|
||||
|
||||
jclass native = Common::Android::GetNativeLibraryClass();
|
||||
jmethodID getExtension = Common::Android::GetFileExtension();
|
||||
|
||||
jstring jext = static_cast<jstring>(env->CallStaticObjectMethod(
|
||||
native,
|
||||
getExtension,
|
||||
jsrc
|
||||
));
|
||||
|
||||
std::string ext = Common::Android::GetJString(env, jext);
|
||||
|
||||
if (ext != extension) {
|
||||
return ErrorWrongFilename;
|
||||
}
|
||||
|
||||
jmethodID copyToStorage = Common::Android::GetCopyToStorage();
|
||||
jstring jdest = Common::Android::ToJString(env, keys_dir.string());
|
||||
|
||||
jboolean copyResult = env->CallStaticBooleanMethod(
|
||||
native,
|
||||
copyToStorage,
|
||||
jsrc,
|
||||
jdest
|
||||
);
|
||||
|
||||
if (!copyResult) {
|
||||
return ErrorFailedCopy;
|
||||
}
|
||||
#else
|
||||
if (!location.ends_with(extension)) {
|
||||
return ErrorWrongFilename;
|
||||
}
|
||||
|
||||
bool prod_keys_found = false;
|
||||
|
||||
const std::filesystem::path prod_key_path = location;
|
||||
const std::filesystem::path key_source_path = prod_key_path.parent_path();
|
||||
|
||||
if (!Common::FS::IsDir(key_source_path)) {
|
||||
return InvalidDir;
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path> source_key_files;
|
||||
|
||||
if (Common::FS::Exists(prod_key_path)) {
|
||||
prod_keys_found = true;
|
||||
source_key_files.emplace_back(prod_key_path);
|
||||
}
|
||||
|
||||
if (Common::FS::Exists(key_source_path / "title.keys")) {
|
||||
source_key_files.emplace_back(key_source_path / "title.keys");
|
||||
}
|
||||
|
||||
if (Common::FS::Exists(key_source_path / "key_retail.bin")) {
|
||||
source_key_files.emplace_back(key_source_path / "key_retail.bin");
|
||||
}
|
||||
|
||||
if (source_key_files.empty() || !prod_keys_found) {
|
||||
return ErrorWrongFilename;
|
||||
}
|
||||
|
||||
for (const auto &key_file : source_key_files) {
|
||||
std::filesystem::path destination_key_file = keys_dir / key_file.filename();
|
||||
if (!std::filesystem::copy_file(key_file,
|
||||
destination_key_file,
|
||||
std::filesystem::copy_options::overwrite_existing)) {
|
||||
LOG_ERROR(Frontend,
|
||||
"Failed to copy file {} to {}",
|
||||
key_file.string(),
|
||||
destination_key_file.string());
|
||||
return ErrorFailedCopy;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Reinitialize the key manager
|
||||
Core::Crypto::KeyManager::Instance().ReloadKeys();
|
||||
|
||||
if (ContentManager::AreKeysPresent()) {
|
||||
return Success;
|
||||
}
|
||||
|
||||
// Let the frontend handle everything else
|
||||
return ErrorFailedInit;
|
||||
}
|
||||
|
||||
FirmwareManager::FirmwareCheckResult FirmwareManager::VerifyFirmware(Core::System &system) {
|
||||
if (!CheckFirmwarePresence(system)) {
|
||||
return ErrorFirmwareMissing;
|
||||
} else {
|
||||
const auto pair = GetFirmwareVersion(system);
|
||||
const auto firmware_data = pair.first;
|
||||
const auto result = pair.second;
|
||||
|
||||
if (result.IsError()) {
|
||||
LOG_INFO(Frontend, "Unable to read firmware");
|
||||
return ErrorFirmwareCorrupted;
|
||||
}
|
||||
|
||||
// TODO: update this whenever newer firmware is properly supported
|
||||
if (firmware_data.major > 19) {
|
||||
return ErrorFirmwareTooNew;
|
||||
}
|
||||
}
|
||||
|
||||
return FirmwareGood;
|
||||
}
|
148
src/frontend_common/firmware_manager.h
Normal file
148
src/frontend_common/firmware_manager.h
Normal file
File diff suppressed because one or more lines are too long
|
@ -10,6 +10,7 @@
|
|||
#include "core/hle/service/am/applet_manager.h"
|
||||
#include "core/loader/nca.h"
|
||||
#include "core/tools/renderdoc.h"
|
||||
#include "frontend_common/firmware_manager.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <unistd.h> // for chdir
|
||||
|
@ -211,7 +212,7 @@ enum class CalloutFlag : uint32_t {
|
|||
* Some games perform worse or straight-up don't work with updates,
|
||||
* so this tracks which games are bad in this regard.
|
||||
*/
|
||||
static const QList<u64> bad_update_games{
|
||||
constexpr std::array<u64, 1> bad_update_games{
|
||||
0x0100F2C0115B6000 // Tears of the Kingdom
|
||||
};
|
||||
|
||||
|
@ -1884,46 +1885,61 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa
|
|||
QSettings settings;
|
||||
QStringList currentIgnored = settings.value("ignoredBadUpdates", {}).toStringList();
|
||||
|
||||
for (const u64 id : bad_update_games) {
|
||||
const bool ignored = currentIgnored.contains(QString::number(id));
|
||||
if (std::find(bad_update_games.begin(), bad_update_games.end(), params.program_id) != bad_update_games.end()
|
||||
&& !currentIgnored.contains(QString::number(params.program_id))) {
|
||||
QMessageBox *msg = new QMessageBox(this);
|
||||
msg->setWindowTitle(tr("Game Updates Warning"));
|
||||
msg->setIcon(QMessageBox::Warning);
|
||||
msg->setText(tr("The game you are trying to launch is known to have performance or booting "
|
||||
"issues when updates are applied. Please try increasing the memory layout to "
|
||||
"6GB or 8GB if any issues occur.<br><br>Press \"OK\" to continue launching, or "
|
||||
"\"Cancel\" to cancel the launch."));
|
||||
|
||||
if (params.program_id == id && !ignored) {
|
||||
QMessageBox *msg = new QMessageBox(this);
|
||||
msg->setWindowTitle(tr("Game Updates Warning"));
|
||||
msg->setIcon(QMessageBox::Warning);
|
||||
msg->setText(tr("The game you are trying to launch is known to have performance or booting "
|
||||
"issues when updates are applied. Please try increasing the memory layout to "
|
||||
"6GB or 8GB if any issues occur.<br><br>Press \"OK\" to continue launching, or "
|
||||
"\"Cancel\" to cancel the launch."));
|
||||
msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
|
||||
// TODO: TMP: Recommends more memory for TotK.
|
||||
QCheckBox *dontShowAgain = new QCheckBox(msg);
|
||||
dontShowAgain->setText(tr("Don't show again for this game"));
|
||||
msg->setCheckBox(dontShowAgain);
|
||||
|
||||
msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
int result = msg->exec();
|
||||
|
||||
QCheckBox *dontShowAgain = new QCheckBox(msg);
|
||||
dontShowAgain->setText(tr("Don't show again for this game"));
|
||||
msg->setCheckBox(dontShowAgain);
|
||||
// wtf
|
||||
QMessageBox::ButtonRole role = msg->buttonRole(msg->button((QMessageBox::StandardButton) result));
|
||||
|
||||
int result = msg->exec();
|
||||
|
||||
// wtf
|
||||
QMessageBox::ButtonRole role = msg->buttonRole(msg->button((QMessageBox::StandardButton) result));
|
||||
|
||||
switch (role) {
|
||||
|
||||
case QMessageBox::RejectRole:
|
||||
return false;
|
||||
|
||||
case QMessageBox::AcceptRole:
|
||||
default:
|
||||
if (dontShowAgain->isChecked()) {
|
||||
currentIgnored << QString::number(params.program_id);
|
||||
|
||||
settings.setValue("ignoredBadUpdates", currentIgnored);
|
||||
settings.sync();
|
||||
}
|
||||
break;
|
||||
switch (role) {
|
||||
case QMessageBox::RejectRole:
|
||||
return false;
|
||||
case QMessageBox::AcceptRole:
|
||||
default:
|
||||
if (dontShowAgain->isChecked()) {
|
||||
currentIgnored << QString::number(params.program_id);
|
||||
settings.setValue("ignoredBadUpdates", currentIgnored);
|
||||
settings.sync();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FirmwareManager::GameRequiresFirmware(params.program_id) && !FirmwareManager::CheckFirmwarePresence(*system)) {
|
||||
QMessageBox *msg = new QMessageBox(this);
|
||||
msg->setWindowTitle(tr("Game Requires Firmware"));
|
||||
msg->setIcon(QMessageBox::Warning);
|
||||
msg->setText(tr("The game you are trying to launch requires firmware to boot or to get past the "
|
||||
"opening menu. Please <a href='https://yuzu-mirror.github.io/help/quickstart'>"
|
||||
"dump and install firmware</a>, or press \"OK\" to launch anyways."));
|
||||
|
||||
msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
|
||||
int exec_result = msg->exec();
|
||||
|
||||
QMessageBox::ButtonRole role = msg->buttonRole(msg->button((QMessageBox::StandardButton) exec_result));
|
||||
|
||||
switch (role) {
|
||||
case QMessageBox::RejectRole:
|
||||
return false;
|
||||
case QMessageBox::AcceptRole:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1940,7 +1956,7 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa
|
|||
UISettings::values.callout_flags = UISettings::values.callout_flags.GetValue() |
|
||||
static_cast<u32>(CalloutFlag::DRDDeprecation);
|
||||
QMessageBox::warning(
|
||||
this, tr("Warning Outdated Game Format"),
|
||||
this, tr("Warning: Outdated Game Format"),
|
||||
tr("You are using the deconstructed ROM directory format for this game, which is an "
|
||||
"outdated format that has been superseded by others such as NCA, NAX, XCI, or "
|
||||
"NSP. Deconstructed ROM directories lack icons, metadata, and update "
|
||||
|
@ -1963,7 +1979,7 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa
|
|||
"This is usually caused by outdated GPU drivers, including integrated ones. "
|
||||
"Please see the log for more details. "
|
||||
"For more information on accessing the log, please see the following page: "
|
||||
"<a href='https://eden-emulator.github.io/help/reference/log-files/'>"
|
||||
"<a href='https://yuzu-mirror.github.io/help/reference/log-files/'>"
|
||||
"How to Upload the Log File</a>. "));
|
||||
break;
|
||||
default:
|
||||
|
@ -4293,8 +4309,8 @@ void GMainWindow::OnInstallFirmware() {
|
|||
progress.close();
|
||||
QMessageBox::warning(
|
||||
this, tr("Firmware install failed"),
|
||||
tr("Firmware installation cancelled, firmware may be in bad state, "
|
||||
"restart eden or re-install firmware."));
|
||||
tr("Firmware installation cancelled, firmware may be in a bad state or corrupted. "
|
||||
"Restart Eden or re-install firmware."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -4339,72 +4355,27 @@ void GMainWindow::OnInstallDecryptionKeys() {
|
|||
}
|
||||
|
||||
const QString key_source_location = QFileDialog::getOpenFileName(
|
||||
this, tr("Select Dumped Keys Location"), {}, QStringLiteral("prod.keys (prod.keys)"), {},
|
||||
this, tr("Select Dumped Keys Location"), {}, QStringLiteral("Decryption Keys (*.keys)"), {},
|
||||
QFileDialog::ReadOnly);
|
||||
if (key_source_location.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify that it contains prod.keys, title.keys and optionally, key_retail.bin
|
||||
LOG_INFO(Frontend, "Installing key files from {}", key_source_location.toStdString());
|
||||
FirmwareManager::KeyInstallResult result = FirmwareManager::InstallKeys(key_source_location.toStdString(), "keys");
|
||||
|
||||
const std::filesystem::path prod_key_path = key_source_location.toStdString();
|
||||
const std::filesystem::path key_source_path = prod_key_path.parent_path();
|
||||
if (!Common::FS::IsDir(key_source_path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool prod_keys_found = false;
|
||||
std::vector<std::filesystem::path> source_key_files;
|
||||
|
||||
if (Common::FS::Exists(prod_key_path)) {
|
||||
prod_keys_found = true;
|
||||
source_key_files.emplace_back(prod_key_path);
|
||||
}
|
||||
|
||||
if (Common::FS::Exists(key_source_path / "title.keys")) {
|
||||
source_key_files.emplace_back(key_source_path / "title.keys");
|
||||
}
|
||||
|
||||
if (Common::FS::Exists(key_source_path / "key_retail.bin")) {
|
||||
source_key_files.emplace_back(key_source_path / "key_retail.bin");
|
||||
}
|
||||
|
||||
// There should be at least prod.keys.
|
||||
if (source_key_files.empty() || !prod_keys_found) {
|
||||
QMessageBox::warning(this, tr("Decryption Keys install failed"),
|
||||
tr("prod.keys is a required decryption key file."));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto yuzu_keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir);
|
||||
for (auto key_file : source_key_files) {
|
||||
std::filesystem::path destination_key_file = yuzu_keys_dir / key_file.filename();
|
||||
if (!std::filesystem::copy_file(key_file, destination_key_file,
|
||||
std::filesystem::copy_options::overwrite_existing)) {
|
||||
LOG_ERROR(Frontend, "Failed to copy file {} to {}", key_file.string(),
|
||||
destination_key_file.string());
|
||||
QMessageBox::critical(this, tr("Decryption Keys install failed"),
|
||||
tr("One or more keys failed to copy."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Reinitialize the key manager, re-read the vfs (for update/dlc files),
|
||||
// and re-populate the game list in the UI if the user has already added
|
||||
// game folders.
|
||||
Core::Crypto::KeyManager::Instance().ReloadKeys();
|
||||
system->GetFileSystemController().CreateFactories(*vfs);
|
||||
game_list->PopulateAsync(UISettings::values.game_dirs);
|
||||
|
||||
if (ContentManager::AreKeysPresent()) {
|
||||
switch (result) {
|
||||
case FirmwareManager::KeyInstallResult::Success:
|
||||
QMessageBox::information(this, tr("Decryption Keys install succeeded"),
|
||||
tr("Decryption Keys were successfully installed"));
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
QMessageBox::critical(
|
||||
this, tr("Decryption Keys install failed"),
|
||||
tr("Decryption Keys failed to initialize. Check that your dumping tools are "
|
||||
"up to date and re-dump keys."));
|
||||
tr(FirmwareManager::GetKeyInstallResultString(result)));
|
||||
break;
|
||||
}
|
||||
|
||||
OnCheckFirmwareDecryption();
|
||||
|
@ -5074,52 +5045,27 @@ void GMainWindow::OnCheckFirmwareDecryption() {
|
|||
|
||||
void GMainWindow::OnCheckFirmware()
|
||||
{
|
||||
if (!CheckFirmwarePresence()) {
|
||||
auto result = FirmwareManager::VerifyFirmware(*system.get());
|
||||
|
||||
switch (result) {
|
||||
case FirmwareManager::FirmwareGood:
|
||||
break;
|
||||
default:
|
||||
QMessageBox::warning(
|
||||
this, tr("Firmware Missing"),
|
||||
tr("Firmware missing. Firmware is required to run certain games and use the Home Menu.\n"
|
||||
"Eden only works with firmware 19.0.1 and earlier."));
|
||||
} else {
|
||||
Service::Set::FirmwareVersionFormat firmware_data{};
|
||||
const auto result = Service::Set::GetFirmwareVersionImpl(
|
||||
firmware_data, *system, Service::Set::GetFirmwareVersionType::Version2);
|
||||
|
||||
if (result.IsError()) {
|
||||
LOG_INFO(Frontend, "Unable to read firmware");
|
||||
QMessageBox::warning(
|
||||
this, tr("Firmware Corrupted"),
|
||||
tr("Firmware reported as present, but was unable to be read. Check for decryption keys and redump firmware if necessary."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (firmware_data.major > 19) {
|
||||
QMessageBox::warning(
|
||||
this, tr("Firmware Too New"),
|
||||
tr("Firmware is too new. Eden only works with firmware 19.0.1 and earlier."));
|
||||
}
|
||||
this, tr("Firmware Read Error"),
|
||||
tr(FirmwareManager::GetFirmwareCheckString(result)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool GMainWindow::CheckFirmwarePresence() {
|
||||
constexpr u64 MiiEditId = static_cast<u64>(Service::AM::AppletProgramId::MiiEdit);
|
||||
|
||||
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
|
||||
if (!bis_system) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto mii_applet_nca = bis_system->GetEntry(MiiEditId, FileSys::ContentRecordType::Program);
|
||||
if (!mii_applet_nca) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return FirmwareManager::CheckFirmwarePresence(*system.get());
|
||||
}
|
||||
|
||||
void GMainWindow::SetFirmwareVersion() {
|
||||
Service::Set::FirmwareVersionFormat firmware_data{};
|
||||
const auto result = Service::Set::GetFirmwareVersionImpl(
|
||||
firmware_data, *system, Service::Set::GetFirmwareVersionType::Version2);
|
||||
const auto pair = FirmwareManager::GetFirmwareVersion(*system.get());
|
||||
const auto firmware_data = pair.first;
|
||||
const auto result = pair.second;
|
||||
|
||||
if (result.IsError() || !CheckFirmwarePresence()) {
|
||||
LOG_INFO(Frontend, "Installed firmware: No firmware available");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue