mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 03:16:54 +02:00
loader: add support for etaHEN cheats
This commit is contained in:
@@ -889,7 +889,7 @@ void ConfigurationListWidget::show_context_menu(const QPoint& pos) {
|
||||
style()->standardIcon(QStyle::SP_FileDialogContentsView), tr("View trophies..."));
|
||||
connect(action_view_trophies, &QAction::triggered, this,
|
||||
&ConfigurationListWidget::ViewTrophies);
|
||||
QAction* action_patches = menu.addAction(tr("Patches (experimental)..."));
|
||||
QAction* action_patches = menu.addAction(tr("Cheats (experimental)..."));
|
||||
connect(action_patches, &QAction::triggered, this, [this, item]() {
|
||||
if (item != nullptr) {
|
||||
auto* dialog = new PatchesDialog(item->GetInfo(), this);
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
PatchesDialog::PatchesDialog(const Configuration& game, QWidget* parent)
|
||||
: QDialog(parent), m_title_id(game.title_id.trimmed().toUpper()) {
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setWindowTitle(tr("Patches (Experimental) - %1").arg(game.name));
|
||||
setWindowTitle(tr("Cheats (Experimental) - %1").arg(game.name));
|
||||
resize(640, 480);
|
||||
|
||||
auto* layout = new QVBoxLayout(this);
|
||||
@@ -54,46 +54,50 @@ QString PatchesDialog::PatchPlanPath(const QString& title_id) {
|
||||
void PatchesDialog::Load() {
|
||||
QFile file(PatchPlanPath(m_title_id));
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
m_status->setText(tr("No local patch file: %1").arg(file.fileName()));
|
||||
m_status->setText(tr("No local cheat file: %1").arg(file.fileName()));
|
||||
m_apply->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto document = QJsonDocument::fromJson(file.readAll());
|
||||
if (document.isNull() || !document.isObject()) {
|
||||
m_status->setText(tr("Invalid patch JSON in %1.").arg(file.fileName()));
|
||||
m_status->setText(tr("Invalid cheat JSON in %1.").arg(file.fileName()));
|
||||
m_apply->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto root = document.object();
|
||||
const auto patches = root.value(QStringLiteral("patches")).toArray();
|
||||
for (const auto& value: patches) {
|
||||
const auto patch = value.toObject();
|
||||
auto* item = new QListWidgetItem(patch.value(QStringLiteral("name")).toString(), m_patches);
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||
item->setCheckState(patch.value(QStringLiteral("enabled")).toBool(true) ? Qt::Checked
|
||||
: Qt::Unchecked);
|
||||
}
|
||||
|
||||
m_apply->setEnabled(!patches.isEmpty());
|
||||
if (patches.isEmpty()) {
|
||||
// shadPS4/ETAHen cheat files use "mods"; Kyty only reads a "patches" array.
|
||||
if (root.contains(QStringLiteral("mods"))) {
|
||||
m_status->setText(
|
||||
tr("This file uses a \"mods\" list. Kyty expects a top-level \"patches\" "
|
||||
"array in %1.")
|
||||
.arg(file.fileName()));
|
||||
} else if (!root.contains(QStringLiteral("patches"))) {
|
||||
m_status->setText(
|
||||
tr("No \"patches\" array in %1.").arg(file.fileName()));
|
||||
} else {
|
||||
m_status->setText(tr("Loaded 0 patch(es) from %1.").arg(file.fileName()));
|
||||
}
|
||||
const auto root = document.object();
|
||||
if (!root.value(QStringLiteral("mods")).isArray()) {
|
||||
m_status->setText(tr("Cheat JSON has no \"mods\" array in %1.").arg(file.fileName()));
|
||||
m_apply->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
m_status->setText(tr("Loaded %1 patch(es) from %2.").arg(patches.size()).arg(file.fileName()));
|
||||
const auto mods = root.value(QStringLiteral("mods")).toArray();
|
||||
for (const auto& value: mods) {
|
||||
if (!value.isObject()) {
|
||||
m_status->setText(tr("Invalid cheat entry in %1.").arg(file.fileName()));
|
||||
m_apply->setEnabled(false);
|
||||
m_patches->clear();
|
||||
return;
|
||||
}
|
||||
const auto mod = value.toObject();
|
||||
const auto name = mod.value(QStringLiteral("name"));
|
||||
const auto enabled = mod.value(QStringLiteral("enabled"));
|
||||
if (!name.isString() || name.toString().isEmpty() ||
|
||||
(!enabled.isUndefined() && !enabled.isBool())) {
|
||||
m_status->setText(tr("Invalid cheat entry in %1.").arg(file.fileName()));
|
||||
m_apply->setEnabled(false);
|
||||
m_patches->clear();
|
||||
return;
|
||||
}
|
||||
auto* item = new QListWidgetItem(name.toString(), m_patches);
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||
item->setCheckState(enabled.toBool(true) ? Qt::Checked : Qt::Unchecked);
|
||||
}
|
||||
|
||||
m_apply->setEnabled(!mods.isEmpty());
|
||||
m_status->setText(tr("Loaded %1 cheat(s) from %2.").arg(mods.size()).arg(file.fileName()));
|
||||
}
|
||||
|
||||
void PatchesDialog::Save() {
|
||||
@@ -105,20 +109,28 @@ void PatchesDialog::Save() {
|
||||
|
||||
auto document = QJsonDocument::fromJson(input.readAll());
|
||||
input.close();
|
||||
auto root = document.object();
|
||||
auto patches = root.value(QStringLiteral("patches")).toArray();
|
||||
for (int index = 0; index < patches.size(); index++) {
|
||||
auto patch = patches[index].toObject();
|
||||
patch.insert(QStringLiteral("enabled"),
|
||||
m_patches->item(index)->checkState() == Qt::Checked);
|
||||
patches[index] = patch;
|
||||
const auto changed_message = tr("Cheat file changed; reload the dialog.");
|
||||
if (!document.isObject()) {
|
||||
m_status->setText(changed_message);
|
||||
return;
|
||||
}
|
||||
root.insert(QStringLiteral("patches"), patches);
|
||||
auto root = document.object();
|
||||
auto mods = root.value(QStringLiteral("mods")).toArray();
|
||||
if (mods.size() != m_patches->count()) {
|
||||
m_status->setText(changed_message);
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < mods.size(); index++) {
|
||||
auto mod = mods[index].toObject();
|
||||
mod.insert(QStringLiteral("enabled"), m_patches->item(index)->checkState() == Qt::Checked);
|
||||
mods[index] = mod;
|
||||
}
|
||||
root.insert(QStringLiteral("mods"), mods);
|
||||
document.setObject(root);
|
||||
|
||||
QSaveFile output(path);
|
||||
if (output.open(QIODevice::WriteOnly) && output.write(document.toJson()) >= 0 &&
|
||||
output.commit()) {
|
||||
m_status->setText(tr("Patch selection saved."));
|
||||
m_status->setText(tr("Cheat selection saved."));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user