@ -37,40 +37,37 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <QFile>
|
||||
#include <QCryptographicHash>
|
||||
#include <Version.h>
|
||||
#include <QDir>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QCryptographicHash>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QSaveFile>
|
||||
#include <QUuid>
|
||||
#include <QTimer>
|
||||
#include <QUuid>
|
||||
|
||||
#include "Exception.h"
|
||||
#include "minecraft/OneSixVersionFormat.h"
|
||||
#include "FileSystem.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "minecraft/ProfileUtils.h"
|
||||
#include "Json.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "minecraft/OneSixVersionFormat.h"
|
||||
#include "minecraft/ProfileUtils.h"
|
||||
|
||||
#include "ComponentUpdateTask.h"
|
||||
#include "PackProfile.h"
|
||||
#include "PackProfile_p.h"
|
||||
#include "ComponentUpdateTask.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include "modplatform/ResourceAPI.h"
|
||||
|
||||
static const QMap<QString, ResourceAPI::ModLoaderType> modloaderMapping{
|
||||
{"net.minecraftforge", ResourceAPI::Forge},
|
||||
{"net.fabricmc.fabric-loader", ResourceAPI::Fabric},
|
||||
{"org.quiltmc.quilt-loader", ResourceAPI::Quilt},
|
||||
{"com.mumfrey.liteloader", ResourceAPI::LiteLoader}
|
||||
};
|
||||
static const QMap<QString, ResourceAPI::ModLoaderType> modloaderMapping{ { "net.minecraftforge", ResourceAPI::Forge },
|
||||
{ "net.fabricmc.fabric-loader", ResourceAPI::Fabric },
|
||||
{ "org.quiltmc.quilt-loader", ResourceAPI::Quilt },
|
||||
{ "com.mumfrey.liteloader", ResourceAPI::LiteLoader } };
|
||||
|
||||
PackProfile::PackProfile(MinecraftInstance * instance)
|
||||
: QAbstractListModel()
|
||||
PackProfile::PackProfile(MinecraftInstance* instance) : QAbstractListModel()
|
||||
{
|
||||
d.reset(new PackProfileData);
|
||||
d->m_instance = instance;
|
||||
@ -95,42 +92,35 @@ static QJsonObject componentToJsonV1(ComponentPtr component)
|
||||
QJsonObject obj;
|
||||
// critical
|
||||
obj.insert("uid", component->m_uid);
|
||||
if(!component->m_version.isEmpty())
|
||||
{
|
||||
if (!component->m_version.isEmpty()) {
|
||||
obj.insert("version", component->m_version);
|
||||
}
|
||||
if(component->m_dependencyOnly)
|
||||
{
|
||||
if (component->m_dependencyOnly) {
|
||||
obj.insert("dependencyOnly", true);
|
||||
}
|
||||
if(component->m_important)
|
||||
{
|
||||
if (component->m_important) {
|
||||
obj.insert("important", true);
|
||||
}
|
||||
if(component->m_disabled)
|
||||
{
|
||||
if (component->m_disabled) {
|
||||
obj.insert("disabled", true);
|
||||
}
|
||||
|
||||
// cached
|
||||
if(!component->m_cachedVersion.isEmpty())
|
||||
{
|
||||
if (!component->m_cachedVersion.isEmpty()) {
|
||||
obj.insert("cachedVersion", component->m_cachedVersion);
|
||||
}
|
||||
if(!component->m_cachedName.isEmpty())
|
||||
{
|
||||
if (!component->m_cachedName.isEmpty()) {
|
||||
obj.insert("cachedName", component->m_cachedName);
|
||||
}
|
||||
Meta::serializeRequires(obj, &component->m_cachedRequires, "cachedRequires");
|
||||
Meta::serializeRequires(obj, &component->m_cachedConflicts, "cachedConflicts");
|
||||
if(component->m_cachedVolatile)
|
||||
{
|
||||
if (component->m_cachedVolatile) {
|
||||
obj.insert("cachedVolatile", true);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
static ComponentPtr componentFromJsonV1(PackProfile * parent, const QString & componentJsonPattern, const QJsonObject &obj)
|
||||
static ComponentPtr componentFromJsonV1(PackProfile* parent, const QString& componentJsonPattern, const QJsonObject& obj)
|
||||
{
|
||||
// critical
|
||||
auto uid = Json::requireString(obj.value("uid"));
|
||||
@ -153,51 +143,44 @@ static ComponentPtr componentFromJsonV1(PackProfile * parent, const QString & co
|
||||
}
|
||||
|
||||
// Save the given component container data to a file
|
||||
static bool savePackProfile(const QString & filename, const ComponentContainer & container)
|
||||
static bool savePackProfile(const QString& filename, const ComponentContainer& container)
|
||||
{
|
||||
QJsonObject obj;
|
||||
obj.insert("formatVersion", currentComponentsFileVersion);
|
||||
QJsonArray orderArray;
|
||||
for(auto component: container)
|
||||
{
|
||||
for (auto component : container) {
|
||||
orderArray.append(componentToJsonV1(component));
|
||||
}
|
||||
obj.insert("components", orderArray);
|
||||
QSaveFile outFile(filename);
|
||||
if (!outFile.open(QFile::WriteOnly))
|
||||
{
|
||||
qCritical() << "Couldn't open" << outFile.fileName()
|
||||
<< "for writing:" << outFile.errorString();
|
||||
if (!outFile.open(QFile::WriteOnly)) {
|
||||
qCritical() << "Couldn't open" << outFile.fileName() << "for writing:" << outFile.errorString();
|
||||
return false;
|
||||
}
|
||||
auto data = QJsonDocument(obj).toJson(QJsonDocument::Indented);
|
||||
if(outFile.write(data) != data.size())
|
||||
{
|
||||
qCritical() << "Couldn't write all the data into" << outFile.fileName()
|
||||
<< "because:" << outFile.errorString();
|
||||
if (outFile.write(data) != data.size()) {
|
||||
qCritical() << "Couldn't write all the data into" << outFile.fileName() << "because:" << outFile.errorString();
|
||||
return false;
|
||||
}
|
||||
if(!outFile.commit())
|
||||
{
|
||||
qCritical() << "Couldn't save" << outFile.fileName()
|
||||
<< "because:" << outFile.errorString();
|
||||
if (!outFile.commit()) {
|
||||
qCritical() << "Couldn't save" << outFile.fileName() << "because:" << outFile.errorString();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Read the given file into component containers
|
||||
static bool loadPackProfile(PackProfile * parent, const QString & filename, const QString & componentJsonPattern, ComponentContainer & container)
|
||||
static bool loadPackProfile(PackProfile* parent,
|
||||
const QString& filename,
|
||||
const QString& componentJsonPattern,
|
||||
ComponentContainer& container)
|
||||
{
|
||||
QFile componentsFile(filename);
|
||||
if (!componentsFile.exists())
|
||||
{
|
||||
if (!componentsFile.exists()) {
|
||||
qWarning() << "Components file doesn't exist. This should never happen.";
|
||||
return false;
|
||||
}
|
||||
if (!componentsFile.open(QFile::ReadOnly))
|
||||
{
|
||||
qCritical() << "Couldn't open" << componentsFile.fileName()
|
||||
<< " for reading:" << componentsFile.errorString();
|
||||
if (!componentsFile.open(QFile::ReadOnly)) {
|
||||
qCritical() << "Couldn't open" << componentsFile.fileName() << " for reading:" << componentsFile.errorString();
|
||||
qWarning() << "Ignoring overriden order";
|
||||
return false;
|
||||
}
|
||||
@ -205,33 +188,26 @@ static bool loadPackProfile(PackProfile * parent, const QString & filename, cons
|
||||
// and it's valid JSON
|
||||
QJsonParseError error;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(componentsFile.readAll(), &error);
|
||||
if (error.error != QJsonParseError::NoError)
|
||||
{
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCritical() << "Couldn't parse" << componentsFile.fileName() << ":" << error.errorString();
|
||||
qWarning() << "Ignoring overriden order";
|
||||
return false;
|
||||
}
|
||||
|
||||
// and then read it and process it if all above is true.
|
||||
try
|
||||
{
|
||||
try {
|
||||
auto obj = Json::requireObject(doc);
|
||||
// check order file version.
|
||||
auto version = Json::requireInteger(obj.value("formatVersion"));
|
||||
if (version != currentComponentsFileVersion)
|
||||
{
|
||||
throw JSONValidationError(QObject::tr("Invalid component file version, expected %1")
|
||||
.arg(currentComponentsFileVersion));
|
||||
if (version != currentComponentsFileVersion) {
|
||||
throw JSONValidationError(QObject::tr("Invalid component file version, expected %1").arg(currentComponentsFileVersion));
|
||||
}
|
||||
auto orderArray = Json::requireArray(obj.value("components"));
|
||||
for(auto item: orderArray)
|
||||
{
|
||||
for (auto item : orderArray) {
|
||||
auto comp_obj = Json::requireObject(item, "Component must be an object.");
|
||||
container.append(componentFromJsonV1(parent, componentJsonPattern, comp_obj));
|
||||
}
|
||||
}
|
||||
catch ([[maybe_unused]] const JSONValidationError &err)
|
||||
{
|
||||
} catch ([[maybe_unused]] const JSONValidationError& err) {
|
||||
qCritical() << "Couldn't parse" << componentsFile.fileName() << ": bad file format";
|
||||
container.clear();
|
||||
return false;
|
||||
@ -245,8 +221,7 @@ static bool loadPackProfile(PackProfile * parent, const QString & filename, cons
|
||||
|
||||
void PackProfile::saveNow()
|
||||
{
|
||||
if(saveIsScheduled())
|
||||
{
|
||||
if (saveIsScheduled()) {
|
||||
d->m_saveTimer.stop();
|
||||
save_internal();
|
||||
}
|
||||
@ -265,13 +240,11 @@ void PackProfile::buildingFromScratch()
|
||||
|
||||
void PackProfile::scheduleSave()
|
||||
{
|
||||
if(!d->loaded)
|
||||
{
|
||||
if (!d->loaded) {
|
||||
qDebug() << "Component list should never save if it didn't successfully load, instance:" << d->m_instance->name();
|
||||
return;
|
||||
}
|
||||
if(!d->dirty)
|
||||
{
|
||||
if (!d->dirty) {
|
||||
d->dirty = true;
|
||||
qDebug() << "Component list save is scheduled for" << d->m_instance->name();
|
||||
}
|
||||
@ -312,26 +285,20 @@ bool PackProfile::load()
|
||||
|
||||
// load the new component list and swap it with the current one...
|
||||
ComponentContainer newComponents;
|
||||
if(!loadPackProfile(this, filename, patchesPattern(), newComponents))
|
||||
{
|
||||
if (!loadPackProfile(this, filename, patchesPattern(), newComponents)) {
|
||||
qCritical() << "Failed to load the component config for instance" << d->m_instance->name();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// FIXME: actually use fine-grained updates, not this...
|
||||
beginResetModel();
|
||||
// disconnect all the old components
|
||||
for(auto component: d->components)
|
||||
{
|
||||
for (auto component : d->components) {
|
||||
disconnect(component.get(), &Component::dataChanged, this, &PackProfile::componentDataChanged);
|
||||
}
|
||||
d->components.clear();
|
||||
d->componentIndex.clear();
|
||||
for(auto component: newComponents)
|
||||
{
|
||||
if(d->componentIndex.contains(component->m_uid))
|
||||
{
|
||||
for (auto component : newComponents) {
|
||||
if (d->componentIndex.contains(component->m_uid)) {
|
||||
qWarning() << "Ignoring duplicate component entry" << component->m_uid;
|
||||
continue;
|
||||
}
|
||||
@ -348,8 +315,7 @@ bool PackProfile::load()
|
||||
void PackProfile::reload(Net::Mode netmode)
|
||||
{
|
||||
// Do not reload when the update/resolve task is running. It is in control.
|
||||
if(d->m_updateTask)
|
||||
{
|
||||
if (d->m_updateTask) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -359,8 +325,7 @@ void PackProfile::reload(Net::Mode netmode)
|
||||
// FIXME: differentiate when a reapply is required by propagating state from components
|
||||
invalidateLaunchProfile();
|
||||
|
||||
if(load())
|
||||
{
|
||||
if (load()) {
|
||||
resolve(netmode);
|
||||
}
|
||||
}
|
||||
@ -376,11 +341,10 @@ void PackProfile::resolve(Net::Mode netmode)
|
||||
d->m_updateTask.reset(updateTask);
|
||||
connect(updateTask, &ComponentUpdateTask::succeeded, this, &PackProfile::updateSucceeded);
|
||||
connect(updateTask, &ComponentUpdateTask::failed, this, &PackProfile::updateFailed);
|
||||
connect(updateTask, &ComponentUpdateTask::aborted, this, [this]{ updateFailed(tr("Aborted")); });
|
||||
connect(updateTask, &ComponentUpdateTask::aborted, this, [this] { updateFailed(tr("Aborted")); });
|
||||
d->m_updateTask->start();
|
||||
}
|
||||
|
||||
|
||||
void PackProfile::updateSucceeded()
|
||||
{
|
||||
qDebug() << "Component list update/resolve task succeeded for" << d->m_instance->name();
|
||||
@ -405,13 +369,11 @@ void PackProfile::appendComponent(ComponentPtr component)
|
||||
void PackProfile::insertComponent(size_t index, ComponentPtr component)
|
||||
{
|
||||
auto id = component->getID();
|
||||
if(id.isEmpty())
|
||||
{
|
||||
if (id.isEmpty()) {
|
||||
qWarning() << "Attempt to add a component with empty ID!";
|
||||
return;
|
||||
}
|
||||
if(d->componentIndex.contains(id))
|
||||
{
|
||||
if (d->componentIndex.contains(id)) {
|
||||
qWarning() << "Attempt to add a component that is already present!";
|
||||
return;
|
||||
}
|
||||
@ -425,21 +387,18 @@ void PackProfile::insertComponent(size_t index, ComponentPtr component)
|
||||
|
||||
void PackProfile::componentDataChanged()
|
||||
{
|
||||
auto objPtr = qobject_cast<Component *>(sender());
|
||||
if(!objPtr)
|
||||
{
|
||||
auto objPtr = qobject_cast<Component*>(sender());
|
||||
if (!objPtr) {
|
||||
qWarning() << "PackProfile got dataChanged signal from a non-Component!";
|
||||
return;
|
||||
}
|
||||
if(objPtr->getID() == "net.minecraft") {
|
||||
if (objPtr->getID() == "net.minecraft") {
|
||||
emit minecraftChanged();
|
||||
}
|
||||
// figure out which one is it... in a seriously dumb way.
|
||||
int index = 0;
|
||||
for (auto component: d->components)
|
||||
{
|
||||
if(component.get() == objPtr)
|
||||
{
|
||||
for (auto component : d->components) {
|
||||
if (component.get() == objPtr) {
|
||||
emit dataChanged(createIndex(index, 0), createIndex(index, columnCount(QModelIndex()) - 1));
|
||||
scheduleSave();
|
||||
return;
|
||||
@ -452,14 +411,12 @@ void PackProfile::componentDataChanged()
|
||||
bool PackProfile::remove(const int index)
|
||||
{
|
||||
auto patch = getComponent(index);
|
||||
if (!patch->isRemovable())
|
||||
{
|
||||
if (!patch->isRemovable()) {
|
||||
qWarning() << "Patch" << patch->getID() << "is non-removable";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!removeComponent_internal(patch))
|
||||
{
|
||||
if (!removeComponent_internal(patch)) {
|
||||
qCritical() << "Patch" << patch->getID() << "could not be removed";
|
||||
return false;
|
||||
}
|
||||
@ -476,10 +433,8 @@ bool PackProfile::remove(const int index)
|
||||
bool PackProfile::remove(const QString id)
|
||||
{
|
||||
int i = 0;
|
||||
for (auto patch : d->components)
|
||||
{
|
||||
if (patch->getID() == id)
|
||||
{
|
||||
for (auto patch : d->components) {
|
||||
if (patch->getID() == id) {
|
||||
return remove(i);
|
||||
}
|
||||
i++;
|
||||
@ -490,13 +445,11 @@ bool PackProfile::remove(const QString id)
|
||||
bool PackProfile::customize(int index)
|
||||
{
|
||||
auto patch = getComponent(index);
|
||||
if (!patch->isCustomizable())
|
||||
{
|
||||
if (!patch->isCustomizable()) {
|
||||
qDebug() << "Patch" << patch->getID() << "is not customizable";
|
||||
return false;
|
||||
}
|
||||
if(!patch->customize())
|
||||
{
|
||||
if (!patch->customize()) {
|
||||
qCritical() << "Patch" << patch->getID() << "could not be customized";
|
||||
return false;
|
||||
}
|
||||
@ -508,13 +461,11 @@ bool PackProfile::customize(int index)
|
||||
bool PackProfile::revertToBase(int index)
|
||||
{
|
||||
auto patch = getComponent(index);
|
||||
if (!patch->isRevertible())
|
||||
{
|
||||
if (!patch->isRevertible()) {
|
||||
qDebug() << "Patch" << patch->getID() << "is not revertible";
|
||||
return false;
|
||||
}
|
||||
if(!patch->revert())
|
||||
{
|
||||
if (!patch->revert()) {
|
||||
qCritical() << "Patch" << patch->getID() << "could not be reverted";
|
||||
return false;
|
||||
}
|
||||
@ -523,11 +474,10 @@ bool PackProfile::revertToBase(int index)
|
||||
return true;
|
||||
}
|
||||
|
||||
ComponentPtr PackProfile::getComponent(const QString &id)
|
||||
ComponentPtr PackProfile::getComponent(const QString& id)
|
||||
{
|
||||
auto iter = d->componentIndex.find(id);
|
||||
if (iter == d->componentIndex.end())
|
||||
{
|
||||
if (iter == d->componentIndex.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return (*iter);
|
||||
@ -535,14 +485,13 @@ ComponentPtr PackProfile::getComponent(const QString &id)
|
||||
|
||||
ComponentPtr PackProfile::getComponent(size_t index)
|
||||
{
|
||||
if(index >= static_cast<size_t>(d->components.size()))
|
||||
{
|
||||
if (index >= static_cast<size_t>(d->components.size())) {
|
||||
return nullptr;
|
||||
}
|
||||
return d->components[index];
|
||||
}
|
||||
|
||||
QVariant PackProfile::data(const QModelIndex &index, int role) const
|
||||
QVariant PackProfile::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
@ -555,72 +504,58 @@ QVariant PackProfile::data(const QModelIndex &index, int role) const
|
||||
|
||||
auto patch = d->components.at(row);
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case Qt::CheckStateRole:
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case NameColumn: {
|
||||
return patch->isEnabled() ? Qt::Checked : Qt::Unchecked;
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
case Qt::DisplayRole:
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case NameColumn:
|
||||
return patch->getName();
|
||||
case VersionColumn:
|
||||
{
|
||||
if(patch->isCustom())
|
||||
{
|
||||
return QString("%1 (Custom)").arg(patch->getVersion());
|
||||
}
|
||||
else
|
||||
{
|
||||
return patch->getVersion();
|
||||
}
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
case Qt::DecorationRole:
|
||||
{
|
||||
if (column == NameColumn) {
|
||||
auto severity = patch->getProblemSeverity();
|
||||
switch (severity)
|
||||
{
|
||||
case ProblemSeverity::Warning:
|
||||
return "warning";
|
||||
case ProblemSeverity::Error:
|
||||
return "error";
|
||||
switch (role) {
|
||||
case Qt::CheckStateRole: {
|
||||
switch (column) {
|
||||
case NameColumn: {
|
||||
return patch->isEnabled() ? Qt::Checked : Qt::Unchecked;
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
case Qt::DisplayRole: {
|
||||
switch (column) {
|
||||
case NameColumn:
|
||||
return patch->getName();
|
||||
case VersionColumn: {
|
||||
if (patch->isCustom()) {
|
||||
return QString("%1 (Custom)").arg(patch->getVersion());
|
||||
} else {
|
||||
return patch->getVersion();
|
||||
}
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
case Qt::DecorationRole: {
|
||||
if (column == NameColumn) {
|
||||
auto severity = patch->getProblemSeverity();
|
||||
switch (severity) {
|
||||
case ProblemSeverity::Warning:
|
||||
return "warning";
|
||||
case ProblemSeverity::Error:
|
||||
return "error";
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool PackProfile::setData(const QModelIndex& index, [[maybe_unused]] const QVariant& value, int role)
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount(index.parent()))
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount(index.parent())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (role == Qt::CheckStateRole)
|
||||
{
|
||||
if (role == Qt::CheckStateRole) {
|
||||
auto component = d->components[index.row()];
|
||||
if (component->setEnabled(!component->isEnabled()))
|
||||
{
|
||||
if (component->setEnabled(!component->isEnabled())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -629,18 +564,15 @@ bool PackProfile::setData(const QModelIndex& index, [[maybe_unused]] const QVari
|
||||
|
||||
QVariant PackProfile::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal)
|
||||
{
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
switch (section)
|
||||
{
|
||||
case NameColumn:
|
||||
return tr("Name");
|
||||
case VersionColumn:
|
||||
return tr("Version");
|
||||
default:
|
||||
return QVariant();
|
||||
if (orientation == Qt::Horizontal) {
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch (section) {
|
||||
case NameColumn:
|
||||
return tr("Name");
|
||||
case VersionColumn:
|
||||
return tr("Version");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -648,7 +580,7 @@ QVariant PackProfile::headerData(int section, Qt::Orientation orientation, int r
|
||||
}
|
||||
|
||||
// FIXME: zero precision mess
|
||||
Qt::ItemFlags PackProfile::flags(const QModelIndex &index) const
|
||||
Qt::ItemFlags PackProfile::flags(const QModelIndex& index) const
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
return Qt::NoItemFlags;
|
||||
@ -664,19 +596,18 @@ Qt::ItemFlags PackProfile::flags(const QModelIndex &index) const
|
||||
|
||||
auto patch = d->components.at(row);
|
||||
// TODO: this will need fine-tuning later...
|
||||
if(patch->canBeDisabled() && !d->interactionDisabled)
|
||||
{
|
||||
if (patch->canBeDisabled() && !d->interactionDisabled) {
|
||||
outFlags |= Qt::ItemIsUserCheckable;
|
||||
}
|
||||
return outFlags;
|
||||
}
|
||||
|
||||
int PackProfile::rowCount(const QModelIndex &parent) const
|
||||
int PackProfile::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : d->components.size();
|
||||
}
|
||||
|
||||
int PackProfile::columnCount(const QModelIndex &parent) const
|
||||
int PackProfile::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : NUM_COLUMNS;
|
||||
}
|
||||
@ -684,12 +615,9 @@ int PackProfile::columnCount(const QModelIndex &parent) const
|
||||
void PackProfile::move(const int index, const MoveDirection direction)
|
||||
{
|
||||
int theirIndex;
|
||||
if (direction == MoveUp)
|
||||
{
|
||||
if (direction == MoveUp) {
|
||||
theirIndex = index - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
theirIndex = index + 1;
|
||||
}
|
||||
|
||||
@ -706,8 +634,7 @@ void PackProfile::move(const int index, const MoveDirection direction)
|
||||
auto from = getComponent(index);
|
||||
auto to = getComponent(theirIndex);
|
||||
|
||||
if (!from || !to || !to->isMoveable() || !from->isMoveable())
|
||||
{
|
||||
if (!from || !to || !to->isMoveable() || !from->isMoveable()) {
|
||||
return;
|
||||
}
|
||||
beginMoveRows(QModelIndex(), index, index, QModelIndex(), togap);
|
||||
@ -775,8 +702,7 @@ void PackProfile::installAgents(QStringList selectedFiles)
|
||||
bool PackProfile::installEmpty(const QString& uid, const QString& name)
|
||||
{
|
||||
QString patchDir = FS::PathCombine(d->m_instance->instanceRoot(), "patches");
|
||||
if(!FS::ensureFolderPathExists(patchDir))
|
||||
{
|
||||
if (!FS::ensureFolderPathExists(patchDir)) {
|
||||
return false;
|
||||
}
|
||||
auto f = std::make_shared<VersionFile>();
|
||||
@ -785,10 +711,8 @@ bool PackProfile::installEmpty(const QString& uid, const QString& name)
|
||||
f->version = "1";
|
||||
QString patchFileName = FS::PathCombine(patchDir, uid + ".json");
|
||||
QFile file(patchFileName);
|
||||
if (!file.open(QFile::WriteOnly))
|
||||
{
|
||||
qCritical() << "Error opening" << file.fileName()
|
||||
<< "for reading:" << file.errorString();
|
||||
if (!file.open(QFile::WriteOnly)) {
|
||||
qCritical() << "Error opening" << file.fileName() << "for reading:" << file.errorString();
|
||||
return false;
|
||||
}
|
||||
file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
|
||||
@ -805,31 +729,25 @@ bool PackProfile::removeComponent_internal(ComponentPtr patch)
|
||||
bool ok = true;
|
||||
// first, remove the patch file. this ensures it's not used anymore
|
||||
auto fileName = patch->getFilename();
|
||||
if(fileName.size())
|
||||
{
|
||||
if (fileName.size()) {
|
||||
QFile patchFile(fileName);
|
||||
if(patchFile.exists() && !patchFile.remove())
|
||||
{
|
||||
if (patchFile.exists() && !patchFile.remove()) {
|
||||
qCritical() << "File" << fileName << "could not be removed because:" << patchFile.errorString();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: we need a generic way of removing local resources, not just jar mods...
|
||||
auto preRemoveJarMod = [&](LibraryPtr jarMod) -> bool
|
||||
{
|
||||
if (!jarMod->isLocal())
|
||||
{
|
||||
auto preRemoveJarMod = [&](LibraryPtr jarMod) -> bool {
|
||||
if (!jarMod->isLocal()) {
|
||||
return true;
|
||||
}
|
||||
QStringList jar, temp1, temp2, temp3;
|
||||
jarMod->getApplicableFiles(d->m_instance->runtimeContext(), jar, temp1, temp2, temp3, d->m_instance->jarmodsPath().absolutePath());
|
||||
QFileInfo finfo (jar[0]);
|
||||
if(finfo.exists())
|
||||
{
|
||||
QFileInfo finfo(jar[0]);
|
||||
if (finfo.exists()) {
|
||||
QFile jarModFile(jar[0]);
|
||||
if(!jarModFile.remove())
|
||||
{
|
||||
if (!jarModFile.remove()) {
|
||||
qCritical() << "File" << jar[0] << "could not be removed because:" << jarModFile.errorString();
|
||||
return false;
|
||||
}
|
||||
@ -839,11 +757,9 @@ bool PackProfile::removeComponent_internal(ComponentPtr patch)
|
||||
};
|
||||
|
||||
auto vFile = patch->getVersionFile();
|
||||
if(vFile)
|
||||
{
|
||||
auto &jarMods = vFile->jarMods;
|
||||
for(auto &jarmod: jarMods)
|
||||
{
|
||||
if (vFile) {
|
||||
auto& jarMods = vFile->jarMods;
|
||||
for (auto& jarmod : jarMods) {
|
||||
ok &= preRemoveJarMod(jarmod);
|
||||
}
|
||||
}
|
||||
@ -853,18 +769,15 @@ bool PackProfile::removeComponent_internal(ComponentPtr patch)
|
||||
bool PackProfile::installJarMods_internal(QStringList filepaths)
|
||||
{
|
||||
QString patchDir = FS::PathCombine(d->m_instance->instanceRoot(), "patches");
|
||||
if(!FS::ensureFolderPathExists(patchDir))
|
||||
{
|
||||
if (!FS::ensureFolderPathExists(patchDir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FS::ensureFolderPathExists(d->m_instance->jarModsDir()))
|
||||
{
|
||||
if (!FS::ensureFolderPathExists(d->m_instance->jarModsDir())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for(auto filepath:filepaths)
|
||||
{
|
||||
for (auto filepath : filepaths) {
|
||||
QFileInfo sourceInfo(filepath);
|
||||
QString id = QUuid::createUuid().toString(QUuid::WithoutBraces);
|
||||
QString target_filename = id + ".jar";
|
||||
@ -875,8 +788,7 @@ bool PackProfile::installJarMods_internal(QStringList filepaths)
|
||||
QFileInfo targetInfo(finalPath);
|
||||
Q_ASSERT(!targetInfo.exists());
|
||||
|
||||
if (!QFile::copy(sourceInfo.absoluteFilePath(),QFileInfo(finalPath).absoluteFilePath()))
|
||||
{
|
||||
if (!QFile::copy(sourceInfo.absoluteFilePath(), QFileInfo(finalPath).absoluteFilePath())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -892,10 +804,8 @@ bool PackProfile::installJarMods_internal(QStringList filepaths)
|
||||
QString patchFileName = FS::PathCombine(patchDir, target_id + ".json");
|
||||
|
||||
QFile file(patchFileName);
|
||||
if (!file.open(QFile::WriteOnly))
|
||||
{
|
||||
qCritical() << "Error opening" << file.fileName()
|
||||
<< "for reading:" << file.errorString();
|
||||
if (!file.open(QFile::WriteOnly)) {
|
||||
qCritical() << "Error opening" << file.fileName() << "for reading:" << file.errorString();
|
||||
return false;
|
||||
}
|
||||
file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
|
||||
@ -911,14 +821,12 @@ bool PackProfile::installJarMods_internal(QStringList filepaths)
|
||||
bool PackProfile::installCustomJar_internal(QString filepath)
|
||||
{
|
||||
QString patchDir = FS::PathCombine(d->m_instance->instanceRoot(), "patches");
|
||||
if(!FS::ensureFolderPathExists(patchDir))
|
||||
{
|
||||
if (!FS::ensureFolderPathExists(patchDir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString libDir = d->m_instance->getLocalLibraryPath();
|
||||
if (!FS::ensureFolderPathExists(libDir))
|
||||
{
|
||||
if (!FS::ensureFolderPathExists(libDir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -930,15 +838,12 @@ bool PackProfile::installCustomJar_internal(QString filepath)
|
||||
QString finalPath = FS::PathCombine(libDir, target_filename);
|
||||
|
||||
QFileInfo jarInfo(finalPath);
|
||||
if (jarInfo.exists())
|
||||
{
|
||||
if(!QFile::remove(finalPath))
|
||||
{
|
||||
if (jarInfo.exists()) {
|
||||
if (!QFile::remove(finalPath)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!QFile::copy(filepath, finalPath))
|
||||
{
|
||||
if (!QFile::copy(filepath, finalPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -953,10 +858,8 @@ bool PackProfile::installCustomJar_internal(QString filepath)
|
||||
QString patchFileName = FS::PathCombine(patchDir, target_id + ".json");
|
||||
|
||||
QFile file(patchFileName);
|
||||
if (!file.open(QFile::WriteOnly))
|
||||
{
|
||||
qCritical() << "Error opening" << file.fileName()
|
||||
<< "for reading:" << file.errorString();
|
||||
if (!file.open(QFile::WriteOnly)) {
|
||||
qCritical() << "Error opening" << file.fileName() << "for reading:" << file.errorString();
|
||||
return false;
|
||||
}
|
||||
file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
|
||||
@ -1029,20 +932,15 @@ bool PackProfile::installAgents_internal(QStringList filepaths)
|
||||
|
||||
std::shared_ptr<LaunchProfile> PackProfile::getProfile() const
|
||||
{
|
||||
if(!d->m_profile)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!d->m_profile) {
|
||||
try {
|
||||
auto profile = std::make_shared<LaunchProfile>();
|
||||
for(auto file: d->components)
|
||||
{
|
||||
for (auto file : d->components) {
|
||||
qDebug() << "Applying" << file->getID() << (file->getProblemSeverity() == ProblemSeverity::Error ? "ERROR" : "GOOD");
|
||||
file->applyTo(profile.get());
|
||||
}
|
||||
d->m_profile = profile;
|
||||
}
|
||||
catch (const Exception &error)
|
||||
{
|
||||
} catch (const Exception& error) {
|
||||
qWarning() << "Couldn't apply profile patches because: " << error.cause();
|
||||
}
|
||||
}
|
||||
@ -1052,20 +950,16 @@ std::shared_ptr<LaunchProfile> PackProfile::getProfile() const
|
||||
bool PackProfile::setComponentVersion(const QString& uid, const QString& version, bool important)
|
||||
{
|
||||
auto iter = d->componentIndex.find(uid);
|
||||
if(iter != d->componentIndex.end())
|
||||
{
|
||||
if (iter != d->componentIndex.end()) {
|
||||
ComponentPtr component = *iter;
|
||||
// set existing
|
||||
if(component->revert())
|
||||
{
|
||||
if (component->revert()) {
|
||||
component->setVersion(version);
|
||||
component->setImportant(important);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// add new
|
||||
auto component = makeShared<Component>(this, uid);
|
||||
component->m_version = version;
|
||||
@ -1078,8 +972,7 @@ bool PackProfile::setComponentVersion(const QString& uid, const QString& version
|
||||
QString PackProfile::getComponentVersion(const QString& uid) const
|
||||
{
|
||||
const auto iter = d->componentIndex.find(uid);
|
||||
if (iter != d->componentIndex.end())
|
||||
{
|
||||
if (iter != d->componentIndex.end()) {
|
||||
return (*iter)->getVersion();
|
||||
}
|
||||
return QString();
|
||||
@ -1087,10 +980,10 @@ QString PackProfile::getComponentVersion(const QString& uid) const
|
||||
|
||||
void PackProfile::disableInteraction(bool disable)
|
||||
{
|
||||
if(d->interactionDisabled != disable) {
|
||||
if (d->interactionDisabled != disable) {
|
||||
d->interactionDisabled = disable;
|
||||
auto size = d->components.size();
|
||||
if(size) {
|
||||
if (size) {
|
||||
emit dataChanged(index(0), index(size - 1));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user