summaryrefslogtreecommitdiffstats
path: root/api/logic/minecraft/MinecraftProfile.cpp
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2017-10-11 23:04:24 +0200
committerPetr Mrázek <peterix@gmail.com>2017-11-04 15:23:49 +0100
commitfede712a26937c5c0815cb9ed62320a8611794eb (patch)
tree1e881f91a01a235bf38710a795ad8add7a728208 /api/logic/minecraft/MinecraftProfile.cpp
parent87edaa7dcd05db10399eda1b2769208a82a54cdf (diff)
downloadMultiMC-fede712a26937c5c0815cb9ed62320a8611794eb.tar
MultiMC-fede712a26937c5c0815cb9ed62320a8611794eb.tar.gz
MultiMC-fede712a26937c5c0815cb9ed62320a8611794eb.tar.lz
MultiMC-fede712a26937c5c0815cb9ed62320a8611794eb.tar.xz
MultiMC-fede712a26937c5c0815cb9ed62320a8611794eb.zip
NOISSUE rename MinecraftProfile to ComponentList
It is realistically a list of components. The fact that it also holds the final launch parameters is a design bug.
Diffstat (limited to 'api/logic/minecraft/MinecraftProfile.cpp')
-rw-r--r--api/logic/minecraft/MinecraftProfile.cpp1125
1 files changed, 0 insertions, 1125 deletions
diff --git a/api/logic/minecraft/MinecraftProfile.cpp b/api/logic/minecraft/MinecraftProfile.cpp
deleted file mode 100644
index a9552af2..00000000
--- a/api/logic/minecraft/MinecraftProfile.cpp
+++ /dev/null
@@ -1,1125 +0,0 @@
-/* Copyright 2013-2017 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <QFile>
-#include <QCryptographicHash>
-#include <Version.h>
-#include <QDir>
-#include <QJsonDocument>
-#include <QJsonArray>
-#include <QDebug>
-
-#include "minecraft/MinecraftProfile.h"
-#include "Exception.h"
-#include <minecraft/OneSixVersionFormat.h>
-#include <FileSystem.h>
-#include <QSaveFile>
-#include <Env.h>
-#include <meta/Index.h>
-#include <minecraft/MinecraftInstance.h>
-#include <QUuid>
-
-MinecraftProfile::MinecraftProfile(MinecraftInstance * instance)
- : QAbstractListModel()
-{
- m_instance = instance;
- clear();
-}
-
-MinecraftProfile::~MinecraftProfile()
-{
-}
-
-void MinecraftProfile::reload()
-{
- beginResetModel();
- load_internal();
- reapplyPatches();
- endResetModel();
-}
-
-void MinecraftProfile::clear()
-{
- m_minecraftVersion.clear();
- m_minecraftVersionType.clear();
- m_minecraftAssets.reset();
- m_minecraftArguments.clear();
- m_tweakers.clear();
- m_mainClass.clear();
- m_appletClass.clear();
- m_libraries.clear();
- m_traits.clear();
- m_jarMods.clear();
- m_mainJar.reset();
- m_problemSeverity = ProblemSeverity::None;
-}
-
-void MinecraftProfile::clearPatches()
-{
- beginResetModel();
- m_patches.clear();
- endResetModel();
-}
-
-void MinecraftProfile::appendPatch(ProfilePatchPtr patch)
-{
- int index = m_patches.size();
- beginInsertRows(QModelIndex(), index, index);
- m_patches.append(patch);
- endInsertRows();
-}
-
-bool MinecraftProfile::remove(const int index)
-{
- auto patch = versionPatch(index);
- if (!patch->isRemovable())
- {
- qDebug() << "Patch" << patch->getID() << "is non-removable";
- return false;
- }
-
- if(!removePatch_internal(patch))
- {
- qCritical() << "Patch" << patch->getID() << "could not be removed";
- return false;
- }
-
- beginRemoveRows(QModelIndex(), index, index);
- m_patches.removeAt(index);
- endRemoveRows();
- reapplyPatches();
- saveCurrentOrder();
- return true;
-}
-
-bool MinecraftProfile::remove(const QString id)
-{
- int i = 0;
- for (auto patch : m_patches)
- {
- if (patch->getID() == id)
- {
- return remove(i);
- }
- i++;
- }
- return false;
-}
-
-bool MinecraftProfile::customize(int index)
-{
- auto patch = versionPatch(index);
- if (!patch->isCustomizable())
- {
- qDebug() << "Patch" << patch->getID() << "is not customizable";
- return false;
- }
- if(!customizePatch_internal(patch))
- {
- qCritical() << "Patch" << patch->getID() << "could not be customized";
- return false;
- }
- reapplyPatches();
- saveCurrentOrder();
- // FIXME: maybe later in unstable
- // emit dataChanged(createIndex(index, 0), createIndex(index, columnCount(QModelIndex()) - 1));
- return true;
-}
-
-bool MinecraftProfile::revertToBase(int index)
-{
- auto patch = versionPatch(index);
- if (!patch->isRevertible())
- {
- qDebug() << "Patch" << patch->getID() << "is not revertible";
- return false;
- }
- if(!revertPatch_internal(patch))
- {
- qCritical() << "Patch" << patch->getID() << "could not be reverted";
- return false;
- }
- reapplyPatches();
- saveCurrentOrder();
- // FIXME: maybe later in unstable
- // emit dataChanged(createIndex(index, 0), createIndex(index, columnCount(QModelIndex()) - 1));
- return true;
-}
-
-ProfilePatchPtr MinecraftProfile::versionPatch(const QString &id)
-{
- for (auto patch : m_patches)
- {
- if (patch->getID() == id)
- {
- return patch;
- }
- }
- return nullptr;
-}
-
-ProfilePatchPtr MinecraftProfile::versionPatch(int index)
-{
- if(index < 0 || index >= m_patches.size())
- return nullptr;
- return m_patches[index];
-}
-
-bool MinecraftProfile::isVanilla()
-{
- for(auto patchptr: m_patches)
- {
- if(patchptr->isCustom())
- return false;
- }
- return true;
-}
-
-bool MinecraftProfile::revertToVanilla()
-{
- // remove patches, if present
- auto VersionPatchesCopy = m_patches;
- for(auto & it: VersionPatchesCopy)
- {
- if (!it->isCustom())
- {
- continue;
- }
- if(it->isRevertible() || it->isRemovable())
- {
- if(!remove(it->getID()))
- {
- qWarning() << "Couldn't remove" << it->getID() << "from profile!";
- reapplyPatches();
- saveCurrentOrder();
- return false;
- }
- }
- }
- reapplyPatches();
- saveCurrentOrder();
- return true;
-}
-
-QVariant MinecraftProfile::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
- int column = index.column();
-
- if (row < 0 || row >= m_patches.size())
- return QVariant();
-
- auto patch = m_patches.at(row);
-
- if (role == Qt::DisplayRole)
- {
- switch (column)
- {
- case 0:
- return m_patches.at(row)->getName();
- case 1:
- {
- if(patch->isCustom())
- {
- return QString("%1 (Custom)").arg(patch->getVersion());
- }
- else
- {
- return patch->getVersion();
- }
- }
- default:
- return QVariant();
- }
- }
- if(role == Qt::DecorationRole)
- {
- switch(column)
- {
- case 0:
- {
- auto severity = patch->getProblemSeverity();
- switch (severity)
- {
- case ProblemSeverity::Warning:
- return "warning";
- case ProblemSeverity::Error:
- return "error";
- default:
- return QVariant();
- }
- }
- default:
- {
- return QVariant();
- }
- }
- }
- return QVariant();
-}
-QVariant MinecraftProfile::headerData(int section, Qt::Orientation orientation, int role) const
-{
- if (orientation == Qt::Horizontal)
- {
- if (role == Qt::DisplayRole)
- {
- switch (section)
- {
- case 0:
- return tr("Name");
- case 1:
- return tr("Version");
- default:
- return QVariant();
- }
- }
- }
- return QVariant();
-}
-Qt::ItemFlags MinecraftProfile::flags(const QModelIndex &index) const
-{
- if (!index.isValid())
- return Qt::NoItemFlags;
- return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
-}
-
-int MinecraftProfile::rowCount(const QModelIndex &parent) const
-{
- return m_patches.size();
-}
-
-int MinecraftProfile::columnCount(const QModelIndex &parent) const
-{
- return 2;
-}
-
-void MinecraftProfile::saveCurrentOrder() const
-{
- ProfileUtils::PatchOrder order;
- for(auto item: m_patches)
- {
- if(!item->isMoveable())
- continue;
- order.append(item->getID());
- }
- saveOrder_internal(order);
-}
-
-void MinecraftProfile::move(const int index, const MoveDirection direction)
-{
- int theirIndex;
- if (direction == MoveUp)
- {
- theirIndex = index - 1;
- }
- else
- {
- theirIndex = index + 1;
- }
-
- if (index < 0 || index >= m_patches.size())
- return;
- if (theirIndex >= rowCount())
- theirIndex = rowCount() - 1;
- if (theirIndex == -1)
- theirIndex = rowCount() - 1;
- if (index == theirIndex)
- return;
- int togap = theirIndex > index ? theirIndex + 1 : theirIndex;
-
- auto from = versionPatch(index);
- auto to = versionPatch(theirIndex);
-
- if (!from || !to || !to->isMoveable() || !from->isMoveable())
- {
- return;
- }
- beginMoveRows(QModelIndex(), index, index, QModelIndex(), togap);
- m_patches.swap(index, theirIndex);
- endMoveRows();
- reapplyPatches();
- saveCurrentOrder();
-}
-void MinecraftProfile::resetOrder()
-{
- resetOrder_internal();
- reload();
-}
-
-bool MinecraftProfile::reapplyPatches()
-{
- try
- {
- clear();
- for(auto file: m_patches)
- {
- qDebug() << "Applying" << file->getID() << (file->getProblemSeverity() == ProblemSeverity::Error ? "ERROR" : "GOOD");
- file->applyTo(this);
- }
- }
- catch (Exception & error)
- {
- clear();
- qWarning() << "Couldn't apply profile patches because: " << error.cause();
- return false;
- }
- return true;
-}
-
-static void applyString(const QString & from, QString & to)
-{
- if(from.isEmpty())
- return;
- to = from;
-}
-
-void MinecraftProfile::applyMinecraftVersion(const QString& id)
-{
- applyString(id, this->m_minecraftVersion);
-}
-
-void MinecraftProfile::applyAppletClass(const QString& appletClass)
-{
- applyString(appletClass, this->m_appletClass);
-}
-
-void MinecraftProfile::applyMainClass(const QString& mainClass)
-{
- applyString(mainClass, this->m_mainClass);
-}
-
-void MinecraftProfile::applyMinecraftArguments(const QString& minecraftArguments)
-{
- applyString(minecraftArguments, this->m_minecraftArguments);
-}
-
-void MinecraftProfile::applyMinecraftVersionType(const QString& type)
-{
- applyString(type, this->m_minecraftVersionType);
-}
-
-void MinecraftProfile::applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets)
-{
- if(assets)
- {
- m_minecraftAssets = assets;
- }
-}
-
-void MinecraftProfile::applyTraits(const QSet<QString>& traits)
-{
- this->m_traits.unite(traits);
-}
-
-void MinecraftProfile::applyTweakers(const QStringList& tweakers)
-{
- // if the applied tweakers override an existing one, skip it. this effectively moves it later in the sequence
- QStringList newTweakers;
- for(auto & tweaker: m_tweakers)
- {
- if (tweakers.contains(tweaker))
- {
- continue;
- }
- newTweakers.append(tweaker);
- }
- // then just append the new tweakers (or moved original ones)
- newTweakers += tweakers;
- m_tweakers = newTweakers;
-}
-
-void MinecraftProfile::applyJarMods(const QList<LibraryPtr>& jarMods)
-{
- this->m_jarMods.append(jarMods);
-}
-
-static int findLibraryByName(QList<LibraryPtr> *haystack, const GradleSpecifier &needle)
-{
- int retval = -1;
- for (int i = 0; i < haystack->size(); ++i)
- {
- if (haystack->at(i)->rawName().matchName(needle))
- {
- // only one is allowed.
- if (retval != -1)
- return -1;
- retval = i;
- }
- }
- return retval;
-}
-
-void MinecraftProfile::applyMods(const QList<LibraryPtr>& mods)
-{
- QList<LibraryPtr> * list = &m_mods;
- for(auto & mod: mods)
- {
- auto modCopy = Library::limitedCopy(mod);
-
- // find the mod by name.
- const int index = findLibraryByName(list, mod->rawName());
- // mod not found? just add it.
- if (index < 0)
- {
- list->append(modCopy);
- return;
- }
-
- auto existingLibrary = list->at(index);
- // if we are higher it means we should update
- if (Version(mod->version()) > Version(existingLibrary->version()))
- {
- list->replace(index, modCopy);
- }
- }
-}
-
-void MinecraftProfile::applyLibrary(LibraryPtr library)
-{
- if(!library->isActive())
- {
- return;
- }
-
- QList<LibraryPtr> * list = &m_libraries;
- if(library->isNative())
- {
- list = &m_nativeLibraries;
- }
-
- auto libraryCopy = Library::limitedCopy(library);
-
- // find the library by name.
- const int index = findLibraryByName(list, library->rawName());
- // library not found? just add it.
- if (index < 0)
- {
- list->append(libraryCopy);
- return;
- }
-
- auto existingLibrary = list->at(index);
- // if we are higher it means we should update
- if (Version(library->version()) > Version(existingLibrary->version()))
- {
- list->replace(index, libraryCopy);
- }
-}
-
-const LibraryPtr MinecraftProfile::getMainJar() const
-{
- return m_mainJar;
-}
-
-void MinecraftProfile::applyMainJar(LibraryPtr jar)
-{
- if(jar)
- {
- m_mainJar = jar;
- }
-}
-
-void MinecraftProfile::applyProblemSeverity(ProblemSeverity severity)
-{
- if (m_problemSeverity < severity)
- {
- m_problemSeverity = severity;
- }
-}
-
-
-QString MinecraftProfile::getMinecraftVersion() const
-{
- return m_minecraftVersion;
-}
-
-QString MinecraftProfile::getAppletClass() const
-{
- return m_appletClass;
-}
-
-QString MinecraftProfile::getMainClass() const
-{
- return m_mainClass;
-}
-
-const QSet<QString> &MinecraftProfile::getTraits() const
-{
- return m_traits;
-}
-
-const QStringList & MinecraftProfile::getTweakers() const
-{
- return m_tweakers;
-}
-
-bool MinecraftProfile::hasTrait(const QString& trait) const
-{
- return m_traits.contains(trait);
-}
-
-ProblemSeverity MinecraftProfile::getProblemSeverity() const
-{
- return m_problemSeverity;
-}
-
-QString MinecraftProfile::getMinecraftVersionType() const
-{
- return m_minecraftVersionType;
-}
-
-std::shared_ptr<MojangAssetIndexInfo> MinecraftProfile::getMinecraftAssets() const
-{
- if(!m_minecraftAssets)
- {
- return std::make_shared<MojangAssetIndexInfo>("legacy");
- }
- return m_minecraftAssets;
-}
-
-QString MinecraftProfile::getMinecraftArguments() const
-{
- return m_minecraftArguments;
-}
-
-const QList<LibraryPtr> & MinecraftProfile::getJarMods() const
-{
- return m_jarMods;
-}
-
-const QList<LibraryPtr> & MinecraftProfile::getLibraries() const
-{
- return m_libraries;
-}
-
-const QList<LibraryPtr> & MinecraftProfile::getNativeLibraries() const
-{
- return m_nativeLibraries;
-}
-
-void MinecraftProfile::getLibraryFiles(const QString& architecture, QStringList& jars, QStringList& nativeJars, const QString& overridePath, const QString& tempPath) const
-{
- QStringList native32, native64;
- jars.clear();
- nativeJars.clear();
- for (auto lib : getLibraries())
- {
- lib->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath);
- }
- // NOTE: order is important here, add main jar last to the lists
- if(m_mainJar)
- {
- // FIXME: HACK!! jar modding is weird and unsystematic!
- if(m_jarMods.size())
- {
- QDir tempDir(tempPath);
- jars.append(tempDir.absoluteFilePath("minecraft.jar"));
- }
- else
- {
- m_mainJar->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath);
- }
- }
- for (auto lib : getNativeLibraries())
- {
- lib->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath);
- }
- if(architecture == "32")
- {
- nativeJars.append(native32);
- }
- else if(architecture == "64")
- {
- nativeJars.append(native64);
- }
-}
-
-void MinecraftProfile::installJarMods(QStringList selectedFiles)
-{
- installJarMods_internal(selectedFiles);
-}
-
-void MinecraftProfile::installCustomJar(QString selectedFile)
-{
- installCustomJar_internal(selectedFile);
-}
-
-
-/*
- * TODO: get rid of this. Get rid of all order numbers.
- */
-int MinecraftProfile::getFreeOrderNumber()
-{
- int largest = 100;
- // yes, I do realize this is dumb. The order thing itself is dumb. and to be removed next.
- for(auto thing: m_patches)
- {
- int order = thing->getOrder();
- if(order > largest)
- largest = order;
- }
- return largest + 1;
-}
-
-void MinecraftProfile::upgradeDeprecatedFiles_internal()
-{
- auto versionJsonPath = FS::PathCombine(m_instance->instanceRoot(), "version.json");
- auto customJsonPath = FS::PathCombine(m_instance->instanceRoot(), "custom.json");
- auto mcJson = FS::PathCombine(m_instance->instanceRoot(), "patches" , "net.minecraft.json");
-
- QString sourceFile;
- QString renameFile;
-
- // convert old crap.
- if(QFile::exists(customJsonPath))
- {
- sourceFile = customJsonPath;
- renameFile = versionJsonPath;
- }
- else if(QFile::exists(versionJsonPath))
- {
- sourceFile = versionJsonPath;
- }
- if(!sourceFile.isEmpty() && !QFile::exists(mcJson))
- {
- if(!FS::ensureFilePathExists(mcJson))
- {
- qWarning() << "Couldn't create patches folder for" << m_instance->name();
- return;
- }
- if(!renameFile.isEmpty() && QFile::exists(renameFile))
- {
- if(!QFile::rename(renameFile, renameFile + ".old"))
- {
- qWarning() << "Couldn't rename" << renameFile << "to" << renameFile + ".old" << "in" << m_instance->name();
- return;
- }
- }
- auto file = ProfileUtils::parseJsonFile(QFileInfo(sourceFile), false);
- ProfileUtils::removeLwjglFromPatch(file);
- file->uid = "net.minecraft";
- file->version = file->minecraftVersion;
- file->name = "Minecraft";
- auto data = OneSixVersionFormat::versionFileToJson(file, false).toJson();
- QSaveFile newPatchFile(mcJson);
- if(!newPatchFile.open(QIODevice::WriteOnly))
- {
- newPatchFile.cancelWriting();
- qWarning() << "Couldn't open main patch for writing in" << m_instance->name();
- return;
- }
- newPatchFile.write(data);
- if(!newPatchFile.commit())
- {
- qWarning() << "Couldn't save main patch in" << m_instance->name();
- return;
- }
- if(!QFile::rename(sourceFile, sourceFile + ".old"))
- {
- qWarning() << "Couldn't rename" << sourceFile << "to" << sourceFile + ".old" << "in" << m_instance->name();
- return;
- }
- }
-}
-
-void MinecraftProfile::loadDefaultBuiltinPatches_internal()
-{
- auto addBuiltinPatch = [&](const QString &uid, const QString intendedVersion, int order)
- {
- auto jsonFilePath = FS::PathCombine(m_instance->instanceRoot(), "patches" , uid + ".json");
- // load up the base minecraft patch
- ProfilePatchPtr profilePatch;
- if(QFile::exists(jsonFilePath))
- {
- auto file = ProfileUtils::parseJsonFile(QFileInfo(jsonFilePath), false);
- if(file->version.isEmpty())
- {
- file->version = intendedVersion;
- }
- profilePatch = std::make_shared<ProfilePatch>(file, jsonFilePath);
- profilePatch->setVanilla(false);
- profilePatch->setRevertible(true);
- }
- else
- {
- auto metaVersion = ENV.metadataIndex()->get(uid, intendedVersion);
- profilePatch = std::make_shared<ProfilePatch>(metaVersion);
- profilePatch->setVanilla(true);
- }
- profilePatch->setOrder(order);
- appendPatch(profilePatch);
- };
- addBuiltinPatch("net.minecraft", m_instance->getComponentVersion("net.minecraft"), -2);
- addBuiltinPatch("org.lwjgl", m_instance->getComponentVersion("org.lwjgl"), -1);
-}
-
-void MinecraftProfile::loadUserPatches_internal()
-{
- // first, collect all patches (that are not builtins of OneSix) and load them
- QMap<QString, ProfilePatchPtr> loadedPatches;
- QDir patchesDir(FS::PathCombine(m_instance->instanceRoot(),"patches"));
- for (auto info : patchesDir.entryInfoList(QStringList() << "*.json", QDir::Files))
- {
- // parse the file
- qDebug() << "Reading" << info.fileName();
- auto file = ProfileUtils::parseJsonFile(info, true);
- // ignore builtins
- if (file->uid == "net.minecraft")
- continue;
- if (file->uid == "org.lwjgl")
- continue;
- auto patch = std::make_shared<ProfilePatch>(file, info.filePath());
- patch->setRemovable(true);
- patch->setMovable(true);
- if(ENV.metadataIndex()->hasUid(file->uid))
- {
- // FIXME: requesting a uid/list creates it in the index... this allows reverting to possibly invalid versions...
- patch->setRevertible(true);
- }
- loadedPatches[file->uid] = patch;
- }
- // these are 'special'... if not already loaded from instance files, grab them from the metadata repo.
- auto loadSpecial = [&](const QString & uid, int order)
- {
- auto patchVersion = m_instance->getComponentVersion(uid);
- if(!patchVersion.isEmpty() && !loadedPatches.contains(uid))
- {
- auto patch = std::make_shared<ProfilePatch>(ENV.metadataIndex()->get(uid, patchVersion));
- patch->setOrder(order);
- patch->setVanilla(true);
- patch->setRemovable(true);
- patch->setMovable(true);
- loadedPatches[uid] = patch;
- }
- };
- loadSpecial("net.minecraftforge", 5);
- loadSpecial("com.mumfrey.liteloader", 10);
-
- // now add all the patches by user sort order
- ProfileUtils::PatchOrder userOrder;
- ProfileUtils::readOverrideOrders(FS::PathCombine(m_instance->instanceRoot(), "order.json"), userOrder);
- for (auto uid : userOrder)
- {
- // ignore builtins
- if (uid == "net.minecraft")
- continue;
- if (uid == "org.lwjgl")
- continue;
- // ordering has a patch that is gone?
- if(!loadedPatches.contains(uid))
- {
- continue;
- }
- appendPatch(loadedPatches.take(uid));
- }
-
- // is there anything left to sort?
- if(loadedPatches.isEmpty())
- {
- // TODO: save the order here?
- return;
- }
-
- // inserting into multimap by order number as key sorts the patches and detects duplicates
- QMultiMap<int, ProfilePatchPtr> files;
- auto iter = loadedPatches.begin();
- while(iter != loadedPatches.end())
- {
- files.insert((*iter)->getOrder(), *iter);
- iter++;
- }
-
- // then just extract the patches and put them in the list
- for (auto order : files.keys())
- {
- const auto &values = files.values(order);
- for(auto &value: values)
- {
- // TODO: put back the insertion of problem messages here, so the user knows about the id duplication
- appendPatch(value);
- }
- }
- // TODO: save the order here?
-}
-
-
-void MinecraftProfile::load_internal()
-{
- clearPatches();
- upgradeDeprecatedFiles_internal();
- loadDefaultBuiltinPatches_internal();
- loadUserPatches_internal();
-}
-
-bool MinecraftProfile::saveOrder_internal(ProfileUtils::PatchOrder order) const
-{
- return ProfileUtils::writeOverrideOrders(FS::PathCombine(m_instance->instanceRoot(), "order.json"), order);
-}
-
-bool MinecraftProfile::resetOrder_internal()
-{
- return QDir(m_instance->instanceRoot()).remove("order.json");
-}
-
-bool MinecraftProfile::removePatch_internal(ProfilePatchPtr patch)
-{
- bool ok = true;
- // first, remove the patch file. this ensures it's not used anymore
- auto fileName = patch->getFilename();
- if(fileName.size())
- {
- QFile patchFile(fileName);
- if(patchFile.exists() && !patchFile.remove())
- {
- qCritical() << "File" << fileName << "could not be removed because:" << patchFile.errorString();
- return false;
- }
- }
- if(!m_instance->getComponentVersion(patch->getID()).isEmpty())
- {
- m_instance->setComponentVersion(patch->getID(), QString());
- }
-
- // FIXME: we need a generic way of removing local resources, not just jar mods...
- auto preRemoveJarMod = [&](LibraryPtr jarMod) -> bool
- {
- if (!jarMod->isLocal())
- {
- return true;
- }
- QStringList jar, temp1, temp2, temp3;
- jarMod->getApplicableFiles(currentSystem, jar, temp1, temp2, temp3, m_instance->jarmodsPath().absolutePath());
- QFileInfo finfo (jar[0]);
- if(finfo.exists())
- {
- QFile jarModFile(jar[0]);
- if(!jarModFile.remove())
- {
- qCritical() << "File" << jar[0] << "could not be removed because:" << jarModFile.errorString();
- return false;
- }
- return true;
- }
- return true;
- };
-
- auto &jarMods = patch->getVersionFile()->jarMods;
- for(auto &jarmod: jarMods)
- {
- ok &= preRemoveJarMod(jarmod);
- }
- return ok;
-}
-
-bool MinecraftProfile::customizePatch_internal(ProfilePatchPtr patch)
-{
- if(patch->isCustom())
- {
- return false;
- }
-
- auto filename = FS::PathCombine(m_instance->instanceRoot(), "patches" , patch->getID() + ".json");
- if(!FS::ensureFilePathExists(filename))
- {
- return false;
- }
- // FIXME: get rid of this try-catch.
- try
- {
- QSaveFile jsonFile(filename);
- if(!jsonFile.open(QIODevice::WriteOnly))
- {
- return false;
- }
- auto vfile = patch->getVersionFile();
- if(!vfile)
- {
- return false;
- }
- auto document = OneSixVersionFormat::versionFileToJson(vfile, true);
- jsonFile.write(document.toJson());
- if(!jsonFile.commit())
- {
- return false;
- }
- load_internal();
- }
- catch (Exception &error)
- {
- qWarning() << "Version could not be loaded:" << error.cause();
- }
- return true;
-}
-
-bool MinecraftProfile::revertPatch_internal(ProfilePatchPtr patch)
-{
- if(!patch->isCustom())
- {
- // already not custom
- return true;
- }
- auto filename = patch->getFilename();
- if(!QFile::exists(filename))
- {
- // already gone / not custom
- return true;
- }
- // just kill the file and reload
- bool result = QFile::remove(filename);
- // FIXME: get rid of this try-catch.
- try
- {
- load_internal();
- }
- catch (Exception &error)
- {
- qWarning() << "Version could not be loaded:" << error.cause();
- }
- return result;
-}
-
-bool MinecraftProfile::installJarMods_internal(QStringList filepaths)
-{
- QString patchDir = FS::PathCombine(m_instance->instanceRoot(), "patches");
- if(!FS::ensureFolderPathExists(patchDir))
- {
- return false;
- }
-
- if (!FS::ensureFolderPathExists(m_instance->jarModsDir()))
- {
- return false;
- }
-
- for(auto filepath:filepaths)
- {
- QFileInfo sourceInfo(filepath);
- auto uuid = QUuid::createUuid();
- QString id = uuid.toString().remove('{').remove('}');
- QString target_filename = id + ".jar";
- QString target_id = "org.multimc.jarmod." + id;
- QString target_name = sourceInfo.completeBaseName() + " (jar mod)";
- QString finalPath = FS::PathCombine(m_instance->jarModsDir(), target_filename);
-
- QFileInfo targetInfo(finalPath);
- if(targetInfo.exists())
- {
- return false;
- }
-
- if (!QFile::copy(sourceInfo.absoluteFilePath(),QFileInfo(finalPath).absoluteFilePath()))
- {
- return false;
- }
-
- auto f = std::make_shared<VersionFile>();
- auto jarMod = std::make_shared<Library>();
- jarMod->setRawName(GradleSpecifier("org.multimc.jarmods:" + id + ":1"));
- jarMod->setFilename(target_filename);
- jarMod->setDisplayName(sourceInfo.completeBaseName());
- jarMod->setHint("local");
- f->jarMods.append(jarMod);
- f->name = target_name;
- f->uid = target_id;
- f->order = getFreeOrderNumber();
- 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();
- return false;
- }
- file.write(OneSixVersionFormat::versionFileToJson(f, true).toJson());
- file.close();
-
- auto patch = std::make_shared<ProfilePatch>(f, patchFileName);
- patch->setMovable(true);
- patch->setRemovable(true);
- appendPatch(patch);
- }
- saveCurrentOrder();
- reapplyPatches();
- return true;
-}
-
-bool MinecraftProfile::installCustomJar_internal(QString filepath)
-{
- QString patchDir = FS::PathCombine(m_instance->instanceRoot(), "patches");
- if(!FS::ensureFolderPathExists(patchDir))
- {
- return false;
- }
-
- QString libDir = m_instance->getLocalLibraryPath();
- if (!FS::ensureFolderPathExists(libDir))
- {
- return false;
- }
-
- auto specifier = GradleSpecifier("org.multimc:customjar:1");
- QFileInfo sourceInfo(filepath);
- QString target_filename = specifier.getFileName();
- QString target_id = specifier.artifactId();
- QString target_name = sourceInfo.completeBaseName() + " (custom jar)";
- QString finalPath = FS::PathCombine(libDir, target_filename);
-
- QFileInfo jarInfo(finalPath);
- if (jarInfo.exists())
- {
- if(!QFile::remove(finalPath))
- {
- return false;
- }
- }
- if (!QFile::copy(filepath, finalPath))
- {
- return false;
- }
-
- auto f = std::make_shared<VersionFile>();
- auto jarMod = std::make_shared<Library>();
- jarMod->setRawName(specifier);
- jarMod->setDisplayName(sourceInfo.completeBaseName());
- jarMod->setHint("local");
- f->mainJar = jarMod;
- f->name = target_name;
- f->uid = target_id;
- f->order = getFreeOrderNumber();
- 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();
- return false;
- }
- file.write(OneSixVersionFormat::versionFileToJson(f, true).toJson());
- file.close();
-
- auto patch = std::make_shared<ProfilePatch>(f, patchFileName);
- patch->setMovable(true);
- patch->setRemovable(true);
- appendPatch(patch);
-
- saveCurrentOrder();
- reapplyPatches();
- return true;
-} \ No newline at end of file