mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-28 13:28:01 +03:00
Loader: deny boot if the firmware is too old
This commit is contained in:
parent
095c884331
commit
949a80dc0a
6 changed files with 39 additions and 18 deletions
|
@ -137,6 +137,7 @@ void fmt_class_string<game_boot_result>::format(std::string& out, u64 arg)
|
||||||
case game_boot_result::decryption_error: return "Failed to decrypt content";
|
case game_boot_result::decryption_error: return "Failed to decrypt content";
|
||||||
case game_boot_result::file_creation_error: return "Could not create important files";
|
case game_boot_result::file_creation_error: return "Could not create important files";
|
||||||
case game_boot_result::firmware_missing: return "Firmware is missing";
|
case game_boot_result::firmware_missing: return "Firmware is missing";
|
||||||
|
case game_boot_result::firmware_version: return "Firmware is too old";
|
||||||
case game_boot_result::unsupported_disc_type: return "This disc type is not supported yet";
|
case game_boot_result::unsupported_disc_type: return "This disc type is not supported yet";
|
||||||
case game_boot_result::savestate_corrupted: return "Savestate data is corrupted or it's not an RPCS3 savestate";
|
case game_boot_result::savestate_corrupted: return "Savestate data is corrupted or it's not an RPCS3 savestate";
|
||||||
case game_boot_result::savestate_version_unsupported: return "Savestate versioning data differs from your RPCS3 build.\nTry to use an older or newer RPCS3 build.\nEspecially if you know the build that created the savestate.";
|
case game_boot_result::savestate_version_unsupported: return "Savestate versioning data differs from your RPCS3 build.\nTry to use an older or newer RPCS3 build.\nEspecially if you know the build that created the savestate.";
|
||||||
|
@ -1965,7 +1966,6 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
|
||||||
// Initialize performance monitor
|
// Initialize performance monitor
|
||||||
g_fxo->init<named_thread<perf_monitor>>();
|
g_fxo->init<named_thread<perf_monitor>>();
|
||||||
|
|
||||||
// Set title to actual disc title if necessary
|
|
||||||
const std::string disc_sfo_dir = vfs::get("/dev_bdvd/PS3_GAME/PARAM.SFO");
|
const std::string disc_sfo_dir = vfs::get("/dev_bdvd/PS3_GAME/PARAM.SFO");
|
||||||
|
|
||||||
const auto disc_psf_obj = psf::load_object(disc_sfo_dir);
|
const auto disc_psf_obj = psf::load_object(disc_sfo_dir);
|
||||||
|
@ -2100,6 +2100,21 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check firmware version
|
||||||
|
if (const std::string_view game_fw_version = psf::get_string(_psf, "PS3_SYSTEM_VER", ""); !game_fw_version.empty())
|
||||||
|
{
|
||||||
|
if (const std::string fw_version = utils::get_firmware_version(); fw_version.empty())
|
||||||
|
{
|
||||||
|
sys_log.warning("Firmware not installed. Skipping required firmware check. (title_id='%s', game_fw='%s')", m_title_id, game_fw_version);
|
||||||
|
}
|
||||||
|
else if (rpcs3::utils::version_is_bigger(game_fw_version, fw_version, m_title_id, true))
|
||||||
|
{
|
||||||
|
sys_log.error("The game's required firmware version is higher than the installed firmware's version. (title_id='%s', game_fw='%s', fw='%s')", m_title_id, game_fw_version, fw_version);
|
||||||
|
return game_boot_result::firmware_version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set title to actual disc title if necessary
|
||||||
if (!disc_psf_obj.empty())
|
if (!disc_psf_obj.empty())
|
||||||
{
|
{
|
||||||
const auto bdvd_title = psf::get_string(disc_psf_obj, "TITLE");
|
const auto bdvd_title = psf::get_string(disc_psf_obj, "TITLE");
|
||||||
|
|
|
@ -51,6 +51,7 @@ enum class game_boot_result : u32
|
||||||
decryption_error,
|
decryption_error,
|
||||||
file_creation_error,
|
file_creation_error,
|
||||||
firmware_missing,
|
firmware_missing,
|
||||||
|
firmware_version,
|
||||||
unsupported_disc_type,
|
unsupported_disc_type,
|
||||||
savestate_corrupted,
|
savestate_corrupted,
|
||||||
savestate_version_unsupported,
|
savestate_version_unsupported,
|
||||||
|
|
|
@ -418,4 +418,19 @@ namespace rpcs3::utils
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool version_is_bigger(std::string_view v0, std::string_view v1, std::string_view serial, bool is_fw)
|
||||||
|
{
|
||||||
|
std::add_pointer_t<char> ev0, ev1;
|
||||||
|
const double ver0 = std::strtod(v0.data(), &ev0);
|
||||||
|
const double ver1 = std::strtod(v1.data(), &ev1);
|
||||||
|
|
||||||
|
if (v0.data() + v0.size() == ev0 && v1.data() + v1.size() == ev1)
|
||||||
|
{
|
||||||
|
return ver0 > ver1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_log.error("Failed to compare the %s numbers for title ID %s: '%s'-'%s'", is_fw ? "firmware version" : "version", serial, v0, v1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,4 +42,6 @@ namespace rpcs3::utils
|
||||||
std::string get_custom_input_config_path(const std::string& title_id);
|
std::string get_custom_input_config_path(const std::string& title_id);
|
||||||
|
|
||||||
std::string get_game_content_path(game_content_type type);
|
std::string get_game_content_path(game_content_type type);
|
||||||
|
|
||||||
|
bool version_is_bigger(std::string_view v0, std::string_view v1, std::string_view serial, bool is_fw);
|
||||||
}
|
}
|
||||||
|
|
|
@ -864,30 +864,15 @@ void game_list_frame::OnRefreshFinished()
|
||||||
if (entry->info.serial != other->info.serial) continue;
|
if (entry->info.serial != other->info.serial) continue;
|
||||||
|
|
||||||
// The patch is game data and must have the same serial and an app version
|
// The patch is game data and must have the same serial and an app version
|
||||||
static constexpr auto version_is_bigger = [](const std::string& v0, const std::string& v1, const std::string& serial, bool is_fw)
|
|
||||||
{
|
|
||||||
std::add_pointer_t<char> ev0, ev1;
|
|
||||||
const double ver0 = std::strtod(v0.c_str(), &ev0);
|
|
||||||
const double ver1 = std::strtod(v1.c_str(), &ev1);
|
|
||||||
|
|
||||||
if (v0.c_str() + v0.size() == ev0 && v1.c_str() + v1.size() == ev1)
|
|
||||||
{
|
|
||||||
return ver0 > ver1;
|
|
||||||
}
|
|
||||||
|
|
||||||
game_list_log.error("Failed to update the displayed %s numbers for title ID %s\n'%s'-'%s'", is_fw ? "firmware version" : "version", serial, v0, v1);
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (other->info.app_ver != cat_unknown_localized)
|
if (other->info.app_ver != cat_unknown_localized)
|
||||||
{
|
{
|
||||||
// Update the app version if it's higher than the disc's version (old games may not have an app version)
|
// Update the app version if it's higher than the disc's version (old games may not have an app version)
|
||||||
if (entry->info.app_ver == cat_unknown_localized || version_is_bigger(other->info.app_ver, entry->info.app_ver, entry->info.serial, true))
|
if (entry->info.app_ver == cat_unknown_localized || rpcs3::utils::version_is_bigger(other->info.app_ver, entry->info.app_ver, entry->info.serial, false))
|
||||||
{
|
{
|
||||||
entry->info.app_ver = other->info.app_ver;
|
entry->info.app_ver = other->info.app_ver;
|
||||||
}
|
}
|
||||||
// Update the firmware version if possible and if it's higher than the disc's version
|
// Update the firmware version if possible and if it's higher than the disc's version
|
||||||
if (other->info.fw != cat_unknown_localized && version_is_bigger(other->info.fw, entry->info.fw, entry->info.serial, false))
|
if (other->info.fw != cat_unknown_localized && rpcs3::utils::version_is_bigger(other->info.fw, entry->info.fw, entry->info.serial, true))
|
||||||
{
|
{
|
||||||
entry->info.fw = other->info.fw;
|
entry->info.fw = other->info.fw;
|
||||||
}
|
}
|
||||||
|
|
|
@ -538,6 +538,9 @@ void main_window::show_boot_error(game_boot_result status)
|
||||||
case game_boot_result::still_running:
|
case game_boot_result::still_running:
|
||||||
message = tr("A game or PS3 application is still running or has yet to be fully stopped.");
|
message = tr("A game or PS3 application is still running or has yet to be fully stopped.");
|
||||||
break;
|
break;
|
||||||
|
case game_boot_result::firmware_version:
|
||||||
|
message = tr("The game or PS3 application needs a more recent firmware version.");
|
||||||
|
break;
|
||||||
case game_boot_result::firmware_missing: // Handled elsewhere
|
case game_boot_result::firmware_missing: // Handled elsewhere
|
||||||
case game_boot_result::already_added: // Handled elsewhere
|
case game_boot_result::already_added: // Handled elsewhere
|
||||||
case game_boot_result::currently_restricted:
|
case game_boot_result::currently_restricted:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue