Qt: Allow package installation through cli

Adds --installpkg cli option
This commit is contained in:
Megamouse 2021-03-21 17:18:25 +01:00
parent 2c05e9719d
commit 554ba9d6a6
7 changed files with 53 additions and 14 deletions

View file

@ -305,6 +305,7 @@ public:
package_reader(const std::string& path); package_reader(const std::string& path);
~package_reader(); ~package_reader();
bool is_valid() const { return m_is_valid; }
package_error check_target_app_version(); package_error check_target_app_version();
bool extract_data(atomic_t<double>& sync); bool extract_data(atomic_t<double>& sync);
psf::registry get_psf() const { return m_psf; } psf::registry get_psf() const { return m_psf; }

View file

@ -13,6 +13,7 @@
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonDocument> #include <QJsonDocument>
#include <QMessageBox>
#include "rpcs3qt/gui_application.h" #include "rpcs3qt/gui_application.h"
#include "rpcs3qt/fatal_error_dialog.h" #include "rpcs3qt/fatal_error_dialog.h"
@ -207,6 +208,7 @@ constexpr auto arg_q_debug = "qDebug";
constexpr auto arg_error = "error"; constexpr auto arg_error = "error";
constexpr auto arg_updating = "updating"; constexpr auto arg_updating = "updating";
constexpr auto arg_installfw = "installfw"; constexpr auto arg_installfw = "installfw";
constexpr auto arg_installpkg = "installpkg";
constexpr auto arg_commit_db = "get-commit-db"; constexpr auto arg_commit_db = "get-commit-db";
int find_arg(std::string arg, int& argc, char* argv[]) int find_arg(std::string arg, int& argc, char* argv[])
@ -511,6 +513,8 @@ int main(int argc, char** argv)
parser.addOption(config_option); parser.addOption(config_option);
const QCommandLineOption installfw_option(arg_installfw, "Forces the emulator to install this firmware file.", "path", ""); const QCommandLineOption installfw_option(arg_installfw, "Forces the emulator to install this firmware file.", "path", "");
parser.addOption(installfw_option); 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_q_debug, "Log qDebug to RPCS3.log.")); parser.addOption(QCommandLineOption(arg_q_debug, "Log qDebug to RPCS3.log."));
parser.addOption(QCommandLineOption(arg_error, "For internal usage.")); parser.addOption(QCommandLineOption(arg_error, "For internal usage."));
parser.addOption(QCommandLineOption(arg_updating, "For internal usage.")); parser.addOption(QCommandLineOption(arg_updating, "For internal usage."));
@ -769,32 +773,41 @@ int main(int argc, char** argv)
Emu.SetConfigOverride(config_override_path); Emu.SetConfigOverride(config_override_path);
} }
std::string firmware_path; // Force install firmware or pkg first if specified through command-line
if (parser.isSet(arg_installfw) || parser.isSet(arg_installpkg))
// Force install firmware first if specified through command-line
if (parser.isSet(arg_installfw))
{ {
if (auto gui_app = qobject_cast<gui_application*>(app.data())) if (auto gui_app = qobject_cast<gui_application*>(app.data()))
{ {
if (s_no_gui) if (s_no_gui)
{ {
report_fatal_error("Cannot install firmware in no-gui mode!"); report_fatal_error("Cannot perform installation in no-gui mode!");
return 1; return 1;
} }
if (gui_app->m_main_window) if (gui_app->m_main_window)
{ {
gui_app->m_main_window->HandlePupInstallation(parser.value(installfw_option)); if (parser.isSet(arg_installfw) && parser.isSet(arg_installpkg))
{
QMessageBox::warning(gui_app->m_main_window, QObject::tr("Invalid command-line arguments!"), QObject::tr("Cannot perform multiple installations at the same time!"));
}
else if (parser.isSet(arg_installfw))
{
gui_app->m_main_window->InstallPup(parser.value(installfw_option));
}
else
{
gui_app->m_main_window->InstallPackages({parser.value(installpkg_option)});
}
} }
else else
{ {
report_fatal_error("Cannot install firmware. No main window found!"); report_fatal_error("Cannot perform installation. No main window found!");
return 1; return 1;
} }
} }
else else
{ {
report_fatal_error("Cannot install firmware in headless mode!"); report_fatal_error("Cannot perform installation in headless mode!");
return 1; return 1;
} }
} }
@ -804,7 +817,7 @@ int main(int argc, char** argv)
sys_log.notice("Option passed via command line: %s %s", opt.toStdString(), parser.value(opt).toStdString()); sys_log.notice("Option passed via command line: %s %s", opt.toStdString(), parser.value(opt).toStdString());
} }
if (const QStringList args = parser.positionalArguments(); !args.isEmpty() && !is_updating && !parser.isSet(arg_installfw)) if (const QStringList args = parser.positionalArguments(); !args.isEmpty() && !is_updating && !parser.isSet(arg_installfw) && !parser.isSet(arg_installpkg))
{ {
sys_log.notice("Booting application from command line: %s", args.at(0).toStdString()); sys_log.notice("Booting application from command line: %s", args.at(0).toStdString());

View file

@ -247,14 +247,21 @@ compat::status game_compatibility::GetStatusData(const QString& status)
compat::package_info game_compatibility::GetPkgInfo(const QString& pkg_path, game_compatibility* compat) compat::package_info game_compatibility::GetPkgInfo(const QString& pkg_path, game_compatibility* compat)
{ {
compat::package_info info;
package_reader reader(pkg_path.toStdString()); package_reader reader(pkg_path.toStdString());
if (!reader.is_valid())
{
info.is_valid = false;
return info;
}
psf::registry psf = reader.get_psf(); psf::registry psf = reader.get_psf();
// TODO: localization of title and changelog // TODO: localization of title and changelog
std::string title_key = "TITLE"; std::string title_key = "TITLE";
std::string changelog_key = "paramhip"; std::string changelog_key = "paramhip";
compat::package_info info;
info.path = pkg_path; info.path = pkg_path;
info.title = qstr(std::string(psf::get_string(psf, title_key))); // Let's read this from the psf first info.title = qstr(std::string(psf::get_string(psf, title_key))); // Let's read this from the psf first
info.title_id = qstr(std::string(psf::get_string(psf, "TITLE_ID"))); info.title_id = qstr(std::string(psf::get_string(psf, "TITLE_ID")));

View file

@ -100,6 +100,8 @@ namespace compat
/** Concicely represents a specific pkg's localized information for use in the GUI */ /** Concicely represents a specific pkg's localized information for use in the GUI */
struct package_info struct package_info
{ {
bool is_valid = true;
QString path; // File path QString path; // File path
QString title_id; // TEST12345 QString title_id; // TEST12345
QString title; // Localized QString title; // Localized

View file

@ -557,12 +557,18 @@ void main_window::InstallPackages(QStringList file_paths)
} }
else if (file_paths.count() == 1) else if (file_paths.count() == 1)
{ {
// This can currently only happen by drag and drop. // This can currently only happen by drag and drop and cli arg.
const QString file_path = file_paths.front(); const QString file_path = file_paths.front();
const QFileInfo file_info(file_path); const QFileInfo file_info(file_path);
compat::package_info info = game_compatibility::GetPkgInfo(file_path, m_game_list_frame ? m_game_list_frame->GetGameCompatibility() : nullptr); compat::package_info info = game_compatibility::GetPkgInfo(file_path, m_game_list_frame ? m_game_list_frame->GetGameCompatibility() : nullptr);
if (!info.is_valid)
{
QMessageBox::warning(this, QObject::tr("Invalid package!"), QObject::tr("The selected package is invalid!\n\nPath:\n%0").arg(file_path));
return;
}
if (info.type != compat::package_type::other) if (info.type != compat::package_type::other)
{ {
if (info.type == compat::package_type::dlc) if (info.type == compat::package_type::dlc)
@ -634,6 +640,11 @@ void main_window::InstallPackages(QStringList file_paths)
void main_window::HandlePackageInstallation(QStringList file_paths) void main_window::HandlePackageInstallation(QStringList file_paths)
{ {
if (file_paths.empty())
{
return;
}
std::vector<compat::package_info> packages; std::vector<compat::package_info> packages;
game_compatibility* compat = m_game_list_frame ? m_game_list_frame->GetGameCompatibility() : nullptr; game_compatibility* compat = m_game_list_frame ? m_game_list_frame->GetGameCompatibility() : nullptr;

View file

@ -85,7 +85,8 @@ public:
bool Init(); bool Init();
QIcon GetAppIcon(); QIcon GetAppIcon();
bool OnMissingFw(); bool OnMissingFw();
void HandlePupInstallation(QString file_path, QString dir_path = ""); void InstallPackages(QStringList file_paths = QStringList());
void InstallPup(QString filePath = "");
Q_SIGNALS: Q_SIGNALS:
void RequestLanguageChange(const QString& language); void RequestLanguageChange(const QString& language);
@ -141,10 +142,9 @@ private:
static bool InstallRapFile(const QString& path, const std::string& filename); static bool InstallRapFile(const QString& path, const std::string& filename);
void InstallPackages(QStringList file_paths = QStringList());
void HandlePackageInstallation(QStringList file_paths); void HandlePackageInstallation(QStringList file_paths);
void InstallPup(QString filePath = ""); void HandlePupInstallation(QString file_path, QString dir_path = "");
void ExtractPup(); void ExtractPup();
void ExtractTar(); void ExtractTar();

View file

@ -28,6 +28,11 @@ pkg_install_dialog::pkg_install_dialog(const QStringList& paths, game_compatibil
for (const QString& path : paths) for (const QString& path : paths)
{ {
const compat::package_info info = game_compatibility::GetPkgInfo(path, compat); const compat::package_info info = game_compatibility::GetPkgInfo(path, compat);
if (!info.is_valid)
{
continue;
}
const QFileInfo file_info(path); const QFileInfo file_info(path);
// We have to build our complicated localized string in some annoying manner // We have to build our complicated localized string in some annoying manner