diff --git a/rpcs3/rpcs3.cpp b/rpcs3/rpcs3.cpp index 9db7ab6da4..4d21f65185 100644 --- a/rpcs3/rpcs3.cpp +++ b/rpcs3/rpcs3.cpp @@ -404,6 +404,8 @@ constexpr auto arg_updating = "updating"; constexpr auto arg_user_id = "user-id"; constexpr auto arg_installfw = "installfw"; constexpr auto arg_installpkg = "installpkg"; +constexpr auto arg_pkg_silent = "silent"; +constexpr auto arg_pkg_no_precompile = "no-precompile"; constexpr auto arg_savestate = "savestate"; constexpr auto arg_rsx_capture = "rsx-capture"; constexpr auto arg_timer = "high-res-timer"; @@ -829,6 +831,8 @@ int run_rpcs3(int argc, char** argv) parser.addOption(installfw_option); const QCommandLineOption installpkg_option(arg_installpkg, "Forces the emulator to install this pkg file.", "path", ""); parser.addOption(installpkg_option); + parser.addOption(QCommandLineOption(arg_pkg_silent, "Install PKG silently without the installation dialog.")); + parser.addOption(QCommandLineOption(arg_pkg_no_precompile, "Skip cache precompilation after PKG install.")); const QCommandLineOption decrypt_option(arg_decrypt, "Decrypt PS3 binaries.", "path(s)", ""); parser.addOption(decrypt_option); const QCommandLineOption user_id_option(arg_user_id, "Start RPCS3 as this user.", "user id", ""); @@ -1163,7 +1167,11 @@ int run_rpcs3(int argc, char** argv) } else { - gui_app->m_main_window->InstallPackages({parser.value(installpkg_option)}); + gui_app->m_main_window->InstallPackages( + {parser.value(installpkg_option)}, + false, + parser.isSet(arg_pkg_silent), + parser.isSet(arg_pkg_no_precompile)); } } else diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index 28f76a63bc..17b07e2617 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -864,7 +864,7 @@ bool main_window::InstallFileInExData(const std::string& extension, const QStrin return to.commit(); } -bool main_window::InstallPackages(QStringList file_paths, bool from_boot) +bool main_window::InstallPackages(QStringList file_paths, bool from_boot, bool silent, bool no_precompile) { if (file_paths.isEmpty()) { @@ -963,19 +963,19 @@ bool main_window::InstallPackages(QStringList file_paths, bool from_boot) if (from_boot) { - return HandlePackageInstallation(file_paths, true); + return HandlePackageInstallation(file_paths, from_boot, silent, no_precompile); } // Handle further installations with a timeout. Otherwise the source explorer instance is not usable during the following file processing. - QTimer::singleShot(0, [this, paths = std::move(file_paths)]() + QTimer::singleShot(0, [this, paths = std::move(file_paths), silent, no_precompile]() { - HandlePackageInstallation(paths, false); + HandlePackageInstallation(paths, false, silent, no_precompile); }); return true; } -bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_boot) +bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_boot, bool silent, bool no_precompile) { if (file_paths.empty()) { @@ -990,28 +990,45 @@ bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_bo const game_compatibility* compat = m_game_list_frame ? m_game_list_frame->GetGameCompatibility() : nullptr; // Let the user choose the packages to install and select the order in which they shall be installed. - pkg_install_dialog dlg(file_paths, from_boot, compat, this); - connect(&dlg, &QDialog::finished, this, [&](int result) + if (silent) { - if (result != QDialog::Accepted) + for (const QString& path : file_paths) { - canceled = true; - return; + const compat::package_info info = game_compatibility::GetPkgInfo(path, nullptr); + if (!info.is_valid) + { + gui_log.error("PKG is invalid or corrupt: %s", path.toStdString()); + return false; + } + packages.push_back(info); } + precompile_caches = !no_precompile; + } + else + { + pkg_install_dialog dlg(file_paths, from_boot, compat, this); + connect(&dlg, &QDialog::finished, this, [&](int result) + { + if (result != QDialog::Accepted) + { + canceled = true; + return; + } - packages = dlg.get_paths_to_install(); - precompile_caches = dlg.precompile_caches(); + packages = dlg.get_paths_to_install(); + precompile_caches = dlg.precompile_caches(); - if (dlg.create_desktop_shortcuts()) - shortcut_locations.insert(gui::utils::shortcut_location::desktop); + if (dlg.create_desktop_shortcuts()) + shortcut_locations.insert(gui::utils::shortcut_location::desktop); - if (dlg.create_app_shortcut()) - shortcut_locations.insert(gui::utils::shortcut_location::applications); + if (dlg.create_app_shortcut()) + shortcut_locations.insert(gui::utils::shortcut_location::applications); - if (dlg.create_steam_shortcut()) - shortcut_locations.insert(gui::utils::shortcut_location::steam); - }); - dlg.exec(); + if (dlg.create_steam_shortcut()) + shortcut_locations.insert(gui::utils::shortcut_location::steam); + }); + dlg.exec(); + } if (canceled) { @@ -1191,39 +1208,45 @@ bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_bo if (!bootable_paths_installed.empty()) { - m_game_list_frame->AddRefreshedSlot([this, shortcut_locations, precompile_caches, paths = std::move(bootable_paths_installed)](std::set& claimed_paths) mutable + if (m_game_list_frame) { - // Try to claim operations on ID - for (auto it = paths.begin(); it != paths.end();) + m_game_list_frame->AddRefreshedSlot([this, shortcut_locations, precompile_caches, paths = std::move(bootable_paths_installed)](std::set& claimed_paths) mutable { - std::string resolved_path = Emu.GetCallbacks().resolve_path(it->first); - - if (resolved_path.empty() || claimed_paths.count(resolved_path)) + // Try to claim operations on ID + for (auto it = paths.begin(); it != paths.end();) { - it = paths.erase(it); + std::string resolved_path = Emu.GetCallbacks().resolve_path(it->first); + + if (resolved_path.empty() || claimed_paths.count(resolved_path)) + { + it = paths.erase(it); + } + else + { + claimed_paths.emplace(std::move(resolved_path)); + it++; + } } - else + + CreateShortCuts(paths, shortcut_locations); + + if (precompile_caches) { - claimed_paths.emplace(std::move(resolved_path)); - it++; + PrecompileCachesFromInstalledPackages(paths); } - } - - CreateShortCuts(paths, shortcut_locations); - - if (precompile_caches) - { - PrecompileCachesFromInstalledPackages(paths); - } - }); + }); + } } - m_game_list_frame->Refresh(true); + if (m_game_list_frame) + { + m_game_list_frame->Refresh(true); + } std::this_thread::sleep_for(std::chrono::microseconds(100'000 - std::min(100'000, get_system_time() - start_time))); pdlg.hide(); - if (installed_a_whole_package_without_new_software) + if (!silent && installed_a_whole_package_without_new_software) { m_gui_settings->ShowInfoBox(tr("Success!"), tr("Successfully installed software from package(s)!"), gui::ib_pkg_success, this); } diff --git a/rpcs3/rpcs3qt/main_window.h b/rpcs3/rpcs3qt/main_window.h index b1dc4847d1..6d46b5e5ef 100644 --- a/rpcs3/rpcs3qt/main_window.h +++ b/rpcs3/rpcs3qt/main_window.h @@ -75,7 +75,7 @@ public: bool Init(bool with_cli_boot); QIcon GetAppIcon() const; void OnMissingFw(); - bool InstallPackages(QStringList file_paths = {}, bool from_boot = false); + bool InstallPackages(QStringList file_paths = {}, bool from_boot = false, bool silent = false, bool no_precompile = false); void InstallPup(QString file_path = ""); Q_SIGNALS: @@ -144,7 +144,7 @@ private: static bool InstallFileInExData(const std::string& extension, const QString& path, const std::string& filename); - bool HandlePackageInstallation(QStringList file_paths, bool from_boot); + bool HandlePackageInstallation(QStringList file_paths, bool from_boot, bool silent = false, bool no_precompile = false); void CreateShortCuts(const std::map& paths, std::set locations); void HandlePupInstallation(const QString& file_path, const QString& dir_path = "");