Add to per game addons tab
Signed-off-by: crueter <crueter@eden-emu.dev>
This commit is contained in:
parent
f222c28c7c
commit
72e9bebf61
|
|
@ -49,10 +49,9 @@ bool InstallMod(const std::filesystem::path& path, const u64 program_id, const b
|
|||
|
||||
// now copy
|
||||
try {
|
||||
if (copy)
|
||||
std::filesystem::copy(path, mod_dir, std::filesystem::copy_options::recursive);
|
||||
else
|
||||
std::filesystem::rename(path, mod_dir);
|
||||
std::filesystem::copy(path, mod_dir, std::filesystem::copy_options::recursive);
|
||||
if (!copy)
|
||||
std::filesystem::remove_all(path);
|
||||
} catch (std::exception& e) {
|
||||
LOG_ERROR(Frontend, "Mod install failed with message {}", e.what());
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include <filesystem>
|
||||
#include <JlCompress.h>
|
||||
#include "frontend_common/mod_manager.h"
|
||||
#include "mod.h"
|
||||
#include "qt_common/abstract/frontend.h"
|
||||
|
|
@ -11,16 +12,18 @@ QString GetModFolder(const QString& root, const QString& fallbackName) {
|
|||
auto std_path = FrontendCommon::GetModFolder(std_root);
|
||||
|
||||
QString default_name;
|
||||
if (std_path)
|
||||
default_name = QString::fromStdString(std_path->filename());
|
||||
else if (fallbackName.isEmpty())
|
||||
default_name = root.split(QLatin1Char('/')).last();
|
||||
else
|
||||
if (!fallbackName.isEmpty())
|
||||
default_name = fallbackName;
|
||||
else if (std_path)
|
||||
default_name = QString::fromStdString(std_path->filename());
|
||||
else
|
||||
default_name = root.split(QLatin1Char('/')).last();
|
||||
|
||||
QString name = QtCommon::Frontend::GetTextInput(
|
||||
tr("Mod Name"), tr("What should this mod be called?"), default_name);
|
||||
|
||||
qDebug() << "Naming mod:" << name;
|
||||
|
||||
// if std_path is empty, frontend_common could not determine mod type and/or name.
|
||||
// so we have to prompt the user and set up the structure ourselves
|
||||
if (!std_path) {
|
||||
|
|
@ -63,6 +66,7 @@ QString GetModFolder(const QString& root, const QString& fallbackName) {
|
|||
|
||||
std_path = mod_dir;
|
||||
|
||||
|
||||
// ... and copy everything from the root to the temp dir
|
||||
for (const auto& entry : fs::directory_iterator(root.toStdString())) {
|
||||
const auto target = tmp / entry.path().filename();
|
||||
|
|
@ -70,8 +74,15 @@ QString GetModFolder(const QString& root, const QString& fallbackName) {
|
|||
fs::copy(entry.path(), target,
|
||||
fs::copy_options::recursive | fs::copy_options::overwrite_existing);
|
||||
}
|
||||
} else {
|
||||
// Rename the existing mod folder.
|
||||
const auto new_path = std_path->parent_path() / name.toStdString();
|
||||
fs::rename(std_path.value(), new_path);
|
||||
std_path = new_path;
|
||||
}
|
||||
|
||||
qDebug() << "Mod path" << std_path->string();
|
||||
|
||||
return QString::fromStdString(std_path->string());
|
||||
}
|
||||
|
||||
|
|
@ -81,4 +92,26 @@ bool InstallMod(const QString& path, const QString& fallbackName, const u64 prog
|
|||
return FrontendCommon::InstallMod(target.toStdString(), program_id, copy);
|
||||
}
|
||||
|
||||
bool InstallModFromZip(const QString& path, const u64 program_id) {
|
||||
namespace fs = std::filesystem;
|
||||
fs::path tmp{fs::temp_directory_path() / "eden" / "unzip_mod"};
|
||||
|
||||
fs::remove_all(tmp);
|
||||
if (!fs::create_directories(tmp))
|
||||
return false;
|
||||
|
||||
QString qCacheDir = QString::fromStdString(tmp.string());
|
||||
|
||||
QFile zip{path};
|
||||
|
||||
// TODO(crueter): use QtCompress
|
||||
QStringList result = JlCompress::extractDir(&zip, qCacheDir);
|
||||
if (result.isEmpty())
|
||||
return false;
|
||||
|
||||
const auto fallback = fs::path{path.toStdString()}.stem();
|
||||
|
||||
return InstallMod(qCacheDir, QString::fromStdString(fallback.string()), program_id, false);
|
||||
}
|
||||
|
||||
} // namespace QtCommon::Mod
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ namespace QtCommon::Mod {
|
|||
|
||||
QString GetModFolder(const QString &root, const QString &fallbackName);
|
||||
|
||||
bool InstallMod(const QString &path, const QString &fallbackName, const u64 program_id, const bool copy);
|
||||
bool InstallMod(const QString &path, const QString &fallbackName, const u64 program_id, const bool copy = true);
|
||||
|
||||
bool InstallModFromZip(const QString &path, const u64 program_id);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,9 @@
|
|||
#include "common/fs/path_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
#include "core/file_sys/xts_archive.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "qt_common/abstract/frontend.h"
|
||||
#include "qt_common/util/mod.h"
|
||||
#include "ui_configure_per_game_addons.h"
|
||||
#include "yuzu/configuration/configure_input.h"
|
||||
#include "yuzu/configuration/configure_per_game_addons.h"
|
||||
|
|
@ -66,6 +67,9 @@ ConfigurePerGameAddons::ConfigurePerGameAddons(Core::System& system_, QWidget* p
|
|||
|
||||
connect(item_model, &QStandardItemModel::itemChanged,
|
||||
[] { UISettings::values.is_game_list_reload_pending.exchange(true); });
|
||||
|
||||
connect(ui->folder, &QAbstractButton::clicked, this, &ConfigurePerGameAddons::InstallModFolder);
|
||||
connect(ui->zip, &QAbstractButton::clicked, this, &ConfigurePerGameAddons::InstallModZip);
|
||||
}
|
||||
|
||||
ConfigurePerGameAddons::~ConfigurePerGameAddons() = default;
|
||||
|
|
@ -99,6 +103,35 @@ void ConfigurePerGameAddons::SetTitleId(u64 id) {
|
|||
this->title_id = id;
|
||||
}
|
||||
|
||||
void ConfigurePerGameAddons::InstallModFolder() {
|
||||
const auto path = QtCommon::Frontend::GetExistingDirectory(tr("Mod Folder"));
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Pending refresh game list
|
||||
if (QtCommon::Mod::InstallMod(path, {}, title_id)) {
|
||||
QtCommon::Frontend::Information(tr("Mod Installed"), tr("Mod was successfully installed."));
|
||||
LoadConfiguration();
|
||||
} else {
|
||||
QtCommon::Frontend::Critical(tr("Mod Install Failed"), tr("Mod install was unsuccessful. Check the log for details."));
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigurePerGameAddons::InstallModZip() {
|
||||
const auto path = QtCommon::Frontend::GetOpenFileName(tr("Zipped Mod Location"), {}, tr("Zipped Archives (*.zip)"));
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (QtCommon::Mod::InstallModFromZip(path, title_id)) {
|
||||
QtCommon::Frontend::Information(tr("Mod Installed"), tr("Mod was successfully installed."));
|
||||
LoadConfiguration();
|
||||
} else {
|
||||
QtCommon::Frontend::Critical(tr("Mod Install Failed"), tr("Mod install was unsuccessful. Check the log for details."));
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigurePerGameAddons::changeEvent(QEvent* event) {
|
||||
if (event->type() == QEvent::LanguageChange) {
|
||||
RetranslateUI();
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include <QList>
|
||||
#include <QWidget>
|
||||
|
||||
#include "core/file_sys/vfs/vfs_types.h"
|
||||
|
||||
|
|
@ -38,6 +39,9 @@ public:
|
|||
|
||||
void SetTitleId(u64 id);
|
||||
|
||||
public slots:
|
||||
void InstallModFolder();
|
||||
void InstallModZip();
|
||||
private:
|
||||
void changeEvent(QEvent* event) override;
|
||||
void RetranslateUI();
|
||||
|
|
|
|||
|
|
@ -17,7 +17,21 @@
|
|||
<string>Add-Ons</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="zip">
|
||||
<property name="text">
|
||||
<string>Import Mod from ZIP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="folder">
|
||||
<property name="text">
|
||||
<string>Import Mod from Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
|
|
@ -28,7 +42,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>380</width>
|
||||
<height>280</height>
|
||||
<height>249</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
|
|||
Loading…
Reference in New Issue