mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
patch_manager: add download button
This commit is contained in:
parent
1e4655aef6
commit
46e8b4f561
@ -98,19 +98,24 @@ static void append_log_message(std::stringstream* log_messages, const std::strin
|
||||
*log_messages << message << std::endl;
|
||||
};
|
||||
|
||||
bool patch_engine::load(patch_map& patches_map, const std::string& path, bool importing, std::stringstream* log_messages)
|
||||
bool patch_engine::load(patch_map& patches_map, const std::string& path, std::string content, bool importing, std::stringstream* log_messages)
|
||||
{
|
||||
// Load patch file
|
||||
fs::file file{ path };
|
||||
|
||||
if (!file)
|
||||
if (content.empty())
|
||||
{
|
||||
// Do nothing
|
||||
return true;
|
||||
// Load patch file
|
||||
fs::file file{path};
|
||||
|
||||
if (!file)
|
||||
{
|
||||
// Do nothing
|
||||
return true;
|
||||
}
|
||||
|
||||
content = file.to_string();
|
||||
}
|
||||
|
||||
// Interpret yaml nodes
|
||||
auto [root, error] = yaml_load(file.to_string());
|
||||
auto [root, error] = yaml_load(content);
|
||||
|
||||
if (!error.empty() || !root)
|
||||
{
|
||||
@ -1059,7 +1064,7 @@ bool patch_engine::import_patches(const patch_engine::patch_map& patches, const
|
||||
{
|
||||
patch_engine::patch_map existing_patches;
|
||||
|
||||
if (load(existing_patches, path, true, log_messages))
|
||||
if (load(existing_patches, path, "", true, log_messages))
|
||||
{
|
||||
append_patches(existing_patches, patches, count, total, log_messages);
|
||||
return count == 0 || save_patches(existing_patches, path, log_messages);
|
||||
|
@ -99,7 +99,7 @@ public:
|
||||
static std::string get_imported_patch_path();
|
||||
|
||||
// Load from file and append to specified patches map
|
||||
static bool load(patch_map& patches, const std::string& path, bool importing = false, std::stringstream* log_messages = nullptr);
|
||||
static bool load(patch_map& patches, const std::string& path, std::string content = "", bool importing = false, std::stringstream* log_messages = nullptr);
|
||||
|
||||
// Read and add a patch node to the patch info
|
||||
static bool read_patch_node(patch_info& info, YAML::Node node, const YAML::Node& root, std::stringstream* log_messages = nullptr);
|
||||
|
@ -15,10 +15,9 @@ size_t curl_write_cb_compat(char* ptr, size_t /*size*/, size_t nmemb, void* user
|
||||
return download->update_buffer(ptr, nmemb);
|
||||
}
|
||||
|
||||
downloader::downloader(const std::string& thread_name, QWidget* parent)
|
||||
downloader::downloader(QWidget* parent)
|
||||
: QObject(parent)
|
||||
, m_parent(parent)
|
||||
, m_thread_name(thread_name)
|
||||
{
|
||||
m_curl = new curl_handle(this);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ class downloader : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
downloader(const std::string& thread_name, QWidget* parent = nullptr);
|
||||
downloader(QWidget* parent = nullptr);
|
||||
|
||||
void start(const std::string& url, bool follow_location, bool show_progress_dialog, const QString& progress_dialog_title = "", bool keep_progress_dialog_open = false, int expected_size = -1);
|
||||
size_t update_buffer(char* data, size_t size);
|
||||
@ -32,7 +32,6 @@ Q_SIGNALS:
|
||||
|
||||
private:
|
||||
QWidget* m_parent = nullptr;
|
||||
std::string m_thread_name;
|
||||
|
||||
curl_handle* m_curl = nullptr;
|
||||
QByteArray m_curl_buf;
|
||||
|
@ -16,7 +16,7 @@ game_compatibility::game_compatibility(std::shared_ptr<gui_settings> settings, Q
|
||||
, m_gui_settings(settings)
|
||||
{
|
||||
m_filepath = m_gui_settings->GetSettingsDir() + "/compat_database.dat";
|
||||
m_downloader = new downloader("Compat Update", parent);
|
||||
m_downloader = new downloader(parent);
|
||||
RequestCompatibility();
|
||||
|
||||
connect(m_downloader, &downloader::signal_download_error, this, &game_compatibility::handle_download_error);
|
||||
|
@ -8,16 +8,19 @@
|
||||
#include <QCheckBox>
|
||||
#include <QMessageBox>
|
||||
#include <QTimer>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "ui_patch_manager_dialog.h"
|
||||
#include "patch_manager_dialog.h"
|
||||
#include "table_item_delegate.h"
|
||||
#include "gui_settings.h"
|
||||
#include "downloader.h"
|
||||
#include "qt_utils.h"
|
||||
#include "Utilities/File.h"
|
||||
#include "util/logs.hpp"
|
||||
|
||||
LOG_CHANNEL(patch_log);
|
||||
LOG_CHANNEL(patch_log, "PAT");
|
||||
|
||||
enum patch_column : int
|
||||
{
|
||||
@ -68,6 +71,10 @@ patch_manager_dialog::patch_manager_dialog(std::shared_ptr<gui_settings> gui_set
|
||||
ui->cb_enable_legacy_patches->setChecked(m_legacy_patches_enabled);
|
||||
ui->cb_owned_games_only->setChecked(m_show_owned_games_only);
|
||||
|
||||
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->setText(tr("Download latest patches"));
|
||||
|
||||
m_downloader = new downloader(parent);
|
||||
|
||||
// Create connects
|
||||
connect(ui->patch_filter, &QLineEdit::textChanged, this, &patch_manager_dialog::filter_patches);
|
||||
connect(ui->patch_tree, &QTreeWidget::currentItemChanged, this, &patch_manager_dialog::handle_item_selected);
|
||||
@ -87,6 +94,23 @@ patch_manager_dialog::patch_manager_dialog(std::shared_ptr<gui_settings> gui_set
|
||||
{
|
||||
save_config();
|
||||
}
|
||||
else if (button == ui->buttonBox->button(QDialogButtonBox::RestoreDefaults))
|
||||
{
|
||||
download_update();
|
||||
}
|
||||
});
|
||||
connect(m_downloader, &downloader::signal_download_error, this, [this](const QString& /*error*/)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Patch downloader"), tr("An error occurred during the download process.\nCheck the log for more information."));
|
||||
});
|
||||
connect(m_downloader, &downloader::signal_download_finished, this, [this](const QByteArray& data)
|
||||
{
|
||||
const bool result_json = handle_json(data);
|
||||
|
||||
if (!result_json)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Patch downloader"), tr("An error occurred during the download process.\nCheck the log for more information."));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -724,7 +748,7 @@ void patch_manager_dialog::dropEvent(QDropEvent* event)
|
||||
patch_engine::patch_map patches;
|
||||
std::stringstream log_message;
|
||||
|
||||
if (patch_engine::load(patches, path, true, &log_message))
|
||||
if (patch_engine::load(patches, path, "", true, &log_message))
|
||||
{
|
||||
patch_log.success("Successfully validated patch file %s", path);
|
||||
|
||||
@ -805,3 +829,96 @@ void patch_manager_dialog::dragLeaveEvent(QDragLeaveEvent* event)
|
||||
{
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void patch_manager_dialog::download_update()
|
||||
{
|
||||
m_downloader->start("https://rpcs3.net/compatibility?patch&api=v1", true, true, tr("Downloading latest patches"));
|
||||
}
|
||||
|
||||
bool patch_manager_dialog::handle_json(const QByteArray& data)
|
||||
{
|
||||
const QJsonObject json_data = QJsonDocument::fromJson(data).object();
|
||||
const int return_code = json_data["return_code"].toInt(-255);
|
||||
|
||||
if (return_code < 0)
|
||||
{
|
||||
std::string error_message;
|
||||
switch (return_code)
|
||||
{
|
||||
case -1: error_message = "Hash not found"; break;
|
||||
case -2: error_message = "Server Error - Maintenance Mode"; break;
|
||||
case -255: error_message = "Server Error - Return code not found"; break;
|
||||
default: error_message = "Server Error - Unknown Error"; break;
|
||||
}
|
||||
|
||||
if (return_code != -1)
|
||||
patch_log.error("Patch download error: %s return code: %d", error_message, return_code);
|
||||
else
|
||||
patch_log.warning("Patch download error: %s return code: %d", error_message, return_code);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const QJsonValue& version_obj = json_data["version"];
|
||||
|
||||
if (!version_obj.isString())
|
||||
{
|
||||
patch_log.error("JSON doesn't contain version");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (const std::string version = version_obj.toString().toStdString();
|
||||
version != patch_engine_version)
|
||||
{
|
||||
patch_log.error("JSON contains wrong version: %s (needed: %s)", version, patch_engine_version);
|
||||
return false;
|
||||
}
|
||||
|
||||
const QJsonValue& patch = json_data["patch"];
|
||||
|
||||
if (!patch.isString() || patch.toString().isEmpty())
|
||||
{
|
||||
patch_log.error("JSON doesn't contain patch");
|
||||
return false;
|
||||
}
|
||||
|
||||
patch_engine::patch_map patches;
|
||||
std::stringstream log_message;
|
||||
|
||||
const std::string content = patch.toString().toStdString();
|
||||
|
||||
if (patch_engine::load(patches, "From Download", content, true, &log_message))
|
||||
{
|
||||
patch_log.success("Successfully validated downloaded patch file");
|
||||
|
||||
const std::string path = patch_engine::get_patches_path() + "patch.yml";
|
||||
const std::string path_old = path + ".old";
|
||||
|
||||
// Back up current patch file
|
||||
if (!fs::copy_file(path, path_old, true))
|
||||
{
|
||||
patch_log.error("Could not back up current patches to %s", path_old);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Overwrite current patch file
|
||||
if (fs::file patch_file = fs::file(path, fs::rewrite))
|
||||
{
|
||||
patch_file.write(content);
|
||||
}
|
||||
else
|
||||
{
|
||||
patch_log.error("Could not save new patches to %s", path);
|
||||
return true;
|
||||
}
|
||||
|
||||
refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
patch_log.error("Errors found in downloaded patch file");
|
||||
QMessageBox::critical(this, tr("Validation failed"), tr("Errors were found in the downloaded patch file.\n\nLog:\n%0").arg(QString::fromStdString(log_message.str())));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ namespace Ui
|
||||
class patch_manager_dialog;
|
||||
}
|
||||
|
||||
class downloader;
|
||||
class gui_settings;
|
||||
|
||||
class patch_manager_dialog : public QDialog
|
||||
@ -55,6 +56,8 @@ private:
|
||||
void save_config();
|
||||
void update_patch_info(const gui_patch_info& info);
|
||||
bool is_valid_file(const QMimeData& md, QStringList* drop_paths = nullptr);
|
||||
void download_update();
|
||||
bool handle_json(const QByteArray& data);
|
||||
|
||||
std::shared_ptr<gui_settings> m_gui_settings;
|
||||
|
||||
@ -64,6 +67,8 @@ private:
|
||||
patch_engine::patch_map m_map;
|
||||
bool m_legacy_patches_enabled = false;
|
||||
|
||||
downloader* m_downloader = nullptr;
|
||||
|
||||
Ui::patch_manager_dialog *ui;
|
||||
|
||||
protected:
|
||||
|
@ -255,7 +255,7 @@
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
|
||||
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::RestoreDefaults|QDialogButtonBox::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -52,7 +52,7 @@ void update_manager::check_for_updates(bool automatic, bool check_only, QWidget*
|
||||
#endif
|
||||
|
||||
m_parent = parent;
|
||||
m_downloader = new downloader("RPCS3 Updater", parent);
|
||||
m_downloader = new downloader(parent);
|
||||
|
||||
connect(m_downloader, &downloader::signal_download_error, this, [this, automatic](const QString& /*error*/)
|
||||
{
|
||||
|
@ -36,12 +36,12 @@ std::pair<YAML::Node, std::string> yaml_load(const std::string& from)
|
||||
{
|
||||
result = YAML::Load(from);
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
return{YAML::Node(), std::string("YAML exception: ") + e.what()};
|
||||
return {YAML::Node(), std::string("YAML exception: ") + e.what()};
|
||||
}
|
||||
|
||||
return{result, ""};
|
||||
return {result, ""};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
Loading…
Reference in New Issue
Block a user