From bbb3b3e6f6e3c0f95873f22e6d0a4aaf350f49d9 Mon Sep 17 00:00:00 2001 From: Petr Mrázek Date: Sun, 15 Jul 2018 14:51:05 +0200 Subject: NOISSUE tabs -> spaces --- api/logic/minecraft/AssetsUtils.cpp | 340 ++-- api/logic/minecraft/AssetsUtils.h | 20 +- api/logic/minecraft/Component.cpp | 604 +++---- api/logic/minecraft/Component.h | 138 +- api/logic/minecraft/ComponentList.cpp | 1896 ++++++++++---------- api/logic/minecraft/ComponentList.h | 138 +- api/logic/minecraft/ComponentList_p.h | 44 +- api/logic/minecraft/ComponentUpdateTask.cpp | 1120 ++++++------ api/logic/minecraft/ComponentUpdateTask.h | 30 +- api/logic/minecraft/ComponentUpdateTask_p.h | 32 +- api/logic/minecraft/GradleSpecifier.h | 266 +-- api/logic/minecraft/GradleSpecifier_test.cpp | 126 +- api/logic/minecraft/LaunchProfile.cpp | 324 ++-- api/logic/minecraft/LaunchProfile.h | 140 +- api/logic/minecraft/Library.cpp | 538 +++--- api/logic/minecraft/Library.h | 330 ++-- api/logic/minecraft/Library_test.cpp | 498 ++--- api/logic/minecraft/MinecraftInstance.cpp | 1410 +++++++-------- api/logic/minecraft/MinecraftInstance.h | 174 +- api/logic/minecraft/MinecraftLoadAndCheck.cpp | 50 +- api/logic/minecraft/MinecraftLoadAndCheck.h | 20 +- api/logic/minecraft/MinecraftUpdate.cpp | 234 +-- api/logic/minecraft/MinecraftUpdate.h | 32 +- api/logic/minecraft/Mod.cpp | 572 +++--- api/logic/minecraft/Mod.h | 228 +-- api/logic/minecraft/ModsModel.cpp | 548 +++--- api/logic/minecraft/ModsModel.h | 152 +- api/logic/minecraft/MojangDownloadInfo.h | 110 +- api/logic/minecraft/MojangVersionFormat.cpp | 578 +++--- api/logic/minecraft/MojangVersionFormat.h | 20 +- api/logic/minecraft/MojangVersionFormat_test.cpp | 76 +- api/logic/minecraft/OneSixVersionFormat.cpp | 650 +++---- api/logic/minecraft/OneSixVersionFormat.h | 28 +- api/logic/minecraft/OpSys.cpp | 36 +- api/logic/minecraft/OpSys.h | 8 +- api/logic/minecraft/ParseUtils.cpp | 36 +- api/logic/minecraft/ParseUtils_test.cpp | 56 +- api/logic/minecraft/ProfileUtils.cpp | 264 +-- api/logic/minecraft/Rule.cpp | 106 +- api/logic/minecraft/Rule.h | 94 +- api/logic/minecraft/SimpleModList.cpp | 552 +++--- api/logic/minecraft/SimpleModList.h | 152 +- api/logic/minecraft/SimpleModList_test.cpp | 70 +- api/logic/minecraft/SkinUpload.cpp | 80 +- api/logic/minecraft/SkinUpload.h | 32 +- api/logic/minecraft/VersionFile.cpp | 68 +- api/logic/minecraft/VersionFile.h | 118 +- api/logic/minecraft/VersionFilterData.cpp | 104 +- api/logic/minecraft/VersionFilterData.h | 24 +- api/logic/minecraft/World.cpp | 560 +++--- api/logic/minecraft/World.h | 102 +- api/logic/minecraft/WorldList.cpp | 510 +++--- api/logic/minecraft/WorldList.h | 174 +- api/logic/minecraft/auth/AuthSession.cpp | 32 +- api/logic/minecraft/auth/AuthSession.h | 70 +- api/logic/minecraft/auth/MojangAccount.cpp | 442 ++--- api/logic/minecraft/auth/MojangAccount.h | 170 +- api/logic/minecraft/auth/MojangAccountList.cpp | 682 +++---- api/logic/minecraft/auth/MojangAccountList.h | 304 ++-- api/logic/minecraft/auth/YggdrasilTask.cpp | 356 ++-- api/logic/minecraft/auth/YggdrasilTask.h | 212 +-- .../minecraft/auth/flows/AuthenticateTask.cpp | 312 ++-- api/logic/minecraft/auth/flows/AuthenticateTask.h | 14 +- api/logic/minecraft/auth/flows/RefreshTask.cpp | 188 +- api/logic/minecraft/auth/flows/RefreshTask.h | 12 +- api/logic/minecraft/auth/flows/ValidateTask.cpp | 32 +- api/logic/minecraft/auth/flows/ValidateTask.h | 12 +- api/logic/minecraft/forge/ForgeXzDownload.cpp | 640 +++---- api/logic/minecraft/forge/ForgeXzDownload.h | 46 +- api/logic/minecraft/launch/ClaimAccount.cpp | 20 +- api/logic/minecraft/launch/ClaimAccount.h | 22 +- .../launch/CreateServerResourcePacksFolder.cpp | 14 +- .../launch/CreateServerResourcePacksFolder.h | 16 +- api/logic/minecraft/launch/DirectJavaLaunch.cpp | 196 +- api/logic/minecraft/launch/DirectJavaLaunch.h | 38 +- api/logic/minecraft/launch/ExtractNatives.cpp | 120 +- api/logic/minecraft/launch/ExtractNatives.h | 18 +- api/logic/minecraft/launch/LauncherPartLaunch.cpp | 292 +-- api/logic/minecraft/launch/LauncherPartLaunch.h | 42 +- api/logic/minecraft/launch/ModMinecraftJar.cpp | 90 +- api/logic/minecraft/launch/ModMinecraftJar.h | 20 +- api/logic/minecraft/launch/PrintInstanceInfo.h | 18 +- api/logic/minecraft/legacy/LegacyInstance.cpp | 226 +-- api/logic/minecraft/legacy/LegacyInstance.h | 216 +-- api/logic/minecraft/legacy/LegacyModList.cpp | 262 +-- api/logic/minecraft/legacy/LegacyModList.h | 28 +- api/logic/minecraft/legacy/LegacyUpgradeTask.cpp | 200 +-- api/logic/minecraft/legacy/LegacyUpgradeTask.h | 18 +- api/logic/minecraft/testdata/lib-native-arch.json | 88 +- api/logic/minecraft/testdata/lib-native.json | 100 +- api/logic/minecraft/testdata/lib-simple.json | 18 +- api/logic/minecraft/update/AssetUpdateTask.cpp | 124 +- api/logic/minecraft/update/AssetUpdateTask.h | 22 +- api/logic/minecraft/update/FMLLibrariesTask.cpp | 190 +- api/logic/minecraft/update/FMLLibrariesTask.h | 22 +- api/logic/minecraft/update/FoldersTask.cpp | 20 +- api/logic/minecraft/update/FoldersTask.h | 10 +- api/logic/minecraft/update/LibrariesTask.cpp | 124 +- api/logic/minecraft/update/LibrariesTask.h | 18 +- 99 files changed, 10364 insertions(+), 10364 deletions(-) (limited to 'api/logic/minecraft') diff --git a/api/logic/minecraft/AssetsUtils.cpp b/api/logic/minecraft/AssetsUtils.cpp index 5b25bede..a2274492 100644 --- a/api/logic/minecraft/AssetsUtils.cpp +++ b/api/logic/minecraft/AssetsUtils.cpp @@ -38,200 +38,200 @@ namespace AssetsUtils */ bool loadAssetsIndexJson(QString assetsId, QString path, AssetsIndex *index) { - /* - { - "objects": { - "icons/icon_16x16.png": { - "hash": "bdf48ef6b5d0d23bbb02e17d04865216179f510a", - "size": 3665 - }, - ... - } - } - } - */ - - QFile file(path); - - // Try to open the file and fail if we can't. - // TODO: We should probably report this error to the user. - if (!file.open(QIODevice::ReadOnly)) - { - qCritical() << "Failed to read assets index file" << path; - return false; - } - index->id = assetsId; - - // Read the file and close it. - QByteArray jsonData = file.readAll(); - file.close(); - - QJsonParseError parseError; - QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError); - - // Fail if the JSON is invalid. - if (parseError.error != QJsonParseError::NoError) - { - qCritical() << "Failed to parse assets index file:" << parseError.errorString() - << "at offset " << QString::number(parseError.offset); - return false; - } - - // Make sure the root is an object. - if (!jsonDoc.isObject()) - { - qCritical() << "Invalid assets index JSON: Root should be an array."; - return false; - } - - QJsonObject root = jsonDoc.object(); - - QJsonValue isVirtual = root.value("virtual"); - if (!isVirtual.isUndefined()) - { - index->isVirtual = isVirtual.toBool(false); - } - - QJsonValue objects = root.value("objects"); - QVariantMap map = objects.toVariant().toMap(); - - for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter) - { - // qDebug() << iter.key(); - - QVariant variant = iter.value(); - QVariantMap nested_objects = variant.toMap(); - - AssetObject object; - - for (QVariantMap::const_iterator nested_iter = nested_objects.begin(); - nested_iter != nested_objects.end(); ++nested_iter) - { - // qDebug() << nested_iter.key() << nested_iter.value().toString(); - QString key = nested_iter.key(); - QVariant value = nested_iter.value(); - - if (key == "hash") - { - object.hash = value.toString(); - } - else if (key == "size") - { - object.size = value.toDouble(); - } - } - - index->objects.insert(iter.key(), object); - } - - return true; + /* + { + "objects": { + "icons/icon_16x16.png": { + "hash": "bdf48ef6b5d0d23bbb02e17d04865216179f510a", + "size": 3665 + }, + ... + } + } + } + */ + + QFile file(path); + + // Try to open the file and fail if we can't. + // TODO: We should probably report this error to the user. + if (!file.open(QIODevice::ReadOnly)) + { + qCritical() << "Failed to read assets index file" << path; + return false; + } + index->id = assetsId; + + // Read the file and close it. + QByteArray jsonData = file.readAll(); + file.close(); + + QJsonParseError parseError; + QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError); + + // Fail if the JSON is invalid. + if (parseError.error != QJsonParseError::NoError) + { + qCritical() << "Failed to parse assets index file:" << parseError.errorString() + << "at offset " << QString::number(parseError.offset); + return false; + } + + // Make sure the root is an object. + if (!jsonDoc.isObject()) + { + qCritical() << "Invalid assets index JSON: Root should be an array."; + return false; + } + + QJsonObject root = jsonDoc.object(); + + QJsonValue isVirtual = root.value("virtual"); + if (!isVirtual.isUndefined()) + { + index->isVirtual = isVirtual.toBool(false); + } + + QJsonValue objects = root.value("objects"); + QVariantMap map = objects.toVariant().toMap(); + + for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter) + { + // qDebug() << iter.key(); + + QVariant variant = iter.value(); + QVariantMap nested_objects = variant.toMap(); + + AssetObject object; + + for (QVariantMap::const_iterator nested_iter = nested_objects.begin(); + nested_iter != nested_objects.end(); ++nested_iter) + { + // qDebug() << nested_iter.key() << nested_iter.value().toString(); + QString key = nested_iter.key(); + QVariant value = nested_iter.value(); + + if (key == "hash") + { + object.hash = value.toString(); + } + else if (key == "size") + { + object.size = value.toDouble(); + } + } + + index->objects.insert(iter.key(), object); + } + + return true; } QDir reconstructAssets(QString assetsId) { - QDir assetsDir = QDir("assets/"); - QDir indexDir = QDir(FS::PathCombine(assetsDir.path(), "indexes")); - QDir objectDir = QDir(FS::PathCombine(assetsDir.path(), "objects")); - QDir virtualDir = QDir(FS::PathCombine(assetsDir.path(), "virtual")); - - QString indexPath = FS::PathCombine(indexDir.path(), assetsId + ".json"); - QFile indexFile(indexPath); - QDir virtualRoot(FS::PathCombine(virtualDir.path(), assetsId)); - - if (!indexFile.exists()) - { - qCritical() << "No assets index file" << indexPath << "; can't reconstruct assets"; - return virtualRoot; - } - - qDebug() << "reconstructAssets" << assetsDir.path() << indexDir.path() - << objectDir.path() << virtualDir.path() << virtualRoot.path(); - - AssetsIndex index; - bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(assetsId, indexPath, &index); - - if (loadAssetsIndex && index.isVirtual) - { - qDebug() << "Reconstructing virtual assets folder at" << virtualRoot.path(); - - for (QString map : index.objects.keys()) - { - AssetObject asset_object = index.objects.value(map); - QString target_path = FS::PathCombine(virtualRoot.path(), map); - QFile target(target_path); - - QString tlk = asset_object.hash.left(2); - - QString original_path = FS::PathCombine(objectDir.path(), tlk, asset_object.hash); - QFile original(original_path); - if (!original.exists()) - continue; - if (!target.exists()) - { - QFileInfo info(target_path); - QDir target_dir = info.dir(); - // qDebug() << target_dir; - if (!target_dir.exists()) - QDir("").mkpath(target_dir.path()); - - bool couldCopy = original.copy(target_path); - qDebug() << " Copying" << original_path << "to" << target_path - << QString::number(couldCopy); // << original.errorString(); - } - } - - // TODO: Write last used time to virtualRoot/.lastused - } - - return virtualRoot; + QDir assetsDir = QDir("assets/"); + QDir indexDir = QDir(FS::PathCombine(assetsDir.path(), "indexes")); + QDir objectDir = QDir(FS::PathCombine(assetsDir.path(), "objects")); + QDir virtualDir = QDir(FS::PathCombine(assetsDir.path(), "virtual")); + + QString indexPath = FS::PathCombine(indexDir.path(), assetsId + ".json"); + QFile indexFile(indexPath); + QDir virtualRoot(FS::PathCombine(virtualDir.path(), assetsId)); + + if (!indexFile.exists()) + { + qCritical() << "No assets index file" << indexPath << "; can't reconstruct assets"; + return virtualRoot; + } + + qDebug() << "reconstructAssets" << assetsDir.path() << indexDir.path() + << objectDir.path() << virtualDir.path() << virtualRoot.path(); + + AssetsIndex index; + bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(assetsId, indexPath, &index); + + if (loadAssetsIndex && index.isVirtual) + { + qDebug() << "Reconstructing virtual assets folder at" << virtualRoot.path(); + + for (QString map : index.objects.keys()) + { + AssetObject asset_object = index.objects.value(map); + QString target_path = FS::PathCombine(virtualRoot.path(), map); + QFile target(target_path); + + QString tlk = asset_object.hash.left(2); + + QString original_path = FS::PathCombine(objectDir.path(), tlk, asset_object.hash); + QFile original(original_path); + if (!original.exists()) + continue; + if (!target.exists()) + { + QFileInfo info(target_path); + QDir target_dir = info.dir(); + // qDebug() << target_dir; + if (!target_dir.exists()) + QDir("").mkpath(target_dir.path()); + + bool couldCopy = original.copy(target_path); + qDebug() << " Copying" << original_path << "to" << target_path + << QString::number(couldCopy); // << original.errorString(); + } + } + + // TODO: Write last used time to virtualRoot/.lastused + } + + return virtualRoot; } } NetActionPtr AssetObject::getDownloadAction() { - QFileInfo objectFile(getLocalPath()); - if ((!objectFile.isFile()) || (objectFile.size() != size)) - { - auto objectDL = Net::Download::makeFile(getUrl(), objectFile.filePath()); - if(hash.size()) - { - auto rawHash = QByteArray::fromHex(hash.toLatin1()); - objectDL->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawHash)); - } - objectDL->m_total_progress = size; - return objectDL; - } - return nullptr; + QFileInfo objectFile(getLocalPath()); + if ((!objectFile.isFile()) || (objectFile.size() != size)) + { + auto objectDL = Net::Download::makeFile(getUrl(), objectFile.filePath()); + if(hash.size()) + { + auto rawHash = QByteArray::fromHex(hash.toLatin1()); + objectDL->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawHash)); + } + objectDL->m_total_progress = size; + return objectDL; + } + return nullptr; } QString AssetObject::getLocalPath() { - return "assets/objects/" + getRelPath(); + return "assets/objects/" + getRelPath(); } QUrl AssetObject::getUrl() { - return QUrl("http://resources.download.minecraft.net/" + getRelPath()); + return QUrl("http://resources.download.minecraft.net/" + getRelPath()); } QString AssetObject::getRelPath() { - return hash.left(2) + "/" + hash; + return hash.left(2) + "/" + hash; } NetJobPtr AssetsIndex::getDownloadJob() { - auto job = new NetJob(QObject::tr("Assets for %1").arg(id)); - for (auto &object : objects.values()) - { - auto dl = object.getDownloadAction(); - if(dl) - { - job->addNetAction(dl); - } - } - if(job->size()) - return job; - return nullptr; + auto job = new NetJob(QObject::tr("Assets for %1").arg(id)); + for (auto &object : objects.values()) + { + auto dl = object.getDownloadAction(); + if(dl) + { + job->addNetAction(dl); + } + } + if(job->size()) + return job; + return nullptr; } diff --git a/api/logic/minecraft/AssetsUtils.h b/api/logic/minecraft/AssetsUtils.h index b7ea9cc1..063c1237 100644 --- a/api/logic/minecraft/AssetsUtils.h +++ b/api/logic/minecraft/AssetsUtils.h @@ -22,22 +22,22 @@ struct AssetObject { - QString getRelPath(); - QUrl getUrl(); - QString getLocalPath(); - NetActionPtr getDownloadAction(); + QString getRelPath(); + QUrl getUrl(); + QString getLocalPath(); + NetActionPtr getDownloadAction(); - QString hash; - qint64 size; + QString hash; + qint64 size; }; struct AssetsIndex { - NetJobPtr getDownloadJob(); + NetJobPtr getDownloadJob(); - QString id; - QMap objects; - bool isVirtual = false; + QString id; + QMap objects; + bool isVirtual = false; }; namespace AssetsUtils diff --git a/api/logic/minecraft/Component.cpp b/api/logic/minecraft/Component.cpp index 7c52271e..51957d17 100644 --- a/api/logic/minecraft/Component.cpp +++ b/api/logic/minecraft/Component.cpp @@ -13,356 +13,356 @@ Component::Component(ComponentList * parent, const QString& uid) { - assert(parent); - m_parent = parent; + assert(parent); + m_parent = parent; - m_uid = uid; + m_uid = uid; } Component::Component(ComponentList * parent, std::shared_ptr version) { - assert(parent); - m_parent = parent; + assert(parent); + m_parent = parent; - m_metaVersion = version; - m_uid = version->uid(); - m_version = m_cachedVersion = version->version(); - m_cachedName = version->name(); - m_loaded = version->isLoaded(); + m_metaVersion = version; + m_uid = version->uid(); + m_version = m_cachedVersion = version->version(); + m_cachedName = version->name(); + m_loaded = version->isLoaded(); } Component::Component(ComponentList * parent, const QString& uid, std::shared_ptr file) { - assert(parent); - m_parent = parent; + assert(parent); + m_parent = parent; - m_file = file; - m_uid = uid; - m_cachedVersion = m_file->version; - m_cachedName = m_file->name; - m_loaded = true; + m_file = file; + m_uid = uid; + m_cachedVersion = m_file->version; + m_cachedName = m_file->name; + m_loaded = true; } std::shared_ptr Component::getMeta() { - return m_metaVersion; + return m_metaVersion; } void Component::applyTo(LaunchProfile* profile) { - // do not apply disabled components - if(!isEnabled()) - { - return; - } - auto vfile = getVersionFile(); - if(vfile) - { - vfile->applyTo(profile); - } - else - { - profile->applyProblemSeverity(getProblemSeverity()); - } + // do not apply disabled components + if(!isEnabled()) + { + return; + } + auto vfile = getVersionFile(); + if(vfile) + { + vfile->applyTo(profile); + } + else + { + profile->applyProblemSeverity(getProblemSeverity()); + } } std::shared_ptr Component::getVersionFile() const { - if(m_metaVersion) - { - if(!m_metaVersion->isLoaded()) - { - m_metaVersion->load(Net::Mode::Online); - } - return m_metaVersion->data(); - } - else - { - return m_file; - } + if(m_metaVersion) + { + if(!m_metaVersion->isLoaded()) + { + m_metaVersion->load(Net::Mode::Online); + } + return m_metaVersion->data(); + } + else + { + return m_file; + } } std::shared_ptr Component::getVersionList() const { - // FIXME: what if the metadata index isn't loaded yet? - if(ENV.metadataIndex()->hasUid(m_uid)) - { - return ENV.metadataIndex()->get(m_uid); - } - return nullptr; + // FIXME: what if the metadata index isn't loaded yet? + if(ENV.metadataIndex()->hasUid(m_uid)) + { + return ENV.metadataIndex()->get(m_uid); + } + return nullptr; } int Component::getOrder() { - if(m_orderOverride) - return m_order; + if(m_orderOverride) + return m_order; - auto vfile = getVersionFile(); - if(vfile) - { - return vfile->order; - } - return 0; + auto vfile = getVersionFile(); + if(vfile) + { + return vfile->order; + } + return 0; } void Component::setOrder(int order) { - m_orderOverride = true; - m_order = order; + m_orderOverride = true; + m_order = order; } QString Component::getID() { - return m_uid; + return m_uid; } QString Component::getName() { - if (!m_cachedName.isEmpty()) - return m_cachedName; - return m_uid; + if (!m_cachedName.isEmpty()) + return m_cachedName; + return m_uid; } QString Component::getVersion() { - return m_cachedVersion; + return m_cachedVersion; } QString Component::getFilename() { - return m_parent->patchFilePathForUid(m_uid); + return m_parent->patchFilePathForUid(m_uid); } QDateTime Component::getReleaseDateTime() { - if(m_metaVersion) - { - return m_metaVersion->time(); - } - auto vfile = getVersionFile(); - if(vfile) - { - return vfile->releaseTime; - } - // FIXME: fake - return QDateTime::currentDateTime(); + if(m_metaVersion) + { + return m_metaVersion->time(); + } + auto vfile = getVersionFile(); + if(vfile) + { + return vfile->releaseTime; + } + // FIXME: fake + return QDateTime::currentDateTime(); } bool Component::isEnabled() { - return !canBeDisabled() || !m_disabled; + return !canBeDisabled() || !m_disabled; } bool Component::canBeDisabled() { - return isRemovable() && !m_dependencyOnly; + return isRemovable() && !m_dependencyOnly; } bool Component::setEnabled(bool state) { - bool intendedDisabled = !state; - if (!canBeDisabled()) - { - intendedDisabled = false; - } - if(intendedDisabled != m_disabled) - { - m_disabled = intendedDisabled; - emit dataChanged(); - return true; - } - return false; + bool intendedDisabled = !state; + if (!canBeDisabled()) + { + intendedDisabled = false; + } + if(intendedDisabled != m_disabled) + { + m_disabled = intendedDisabled; + emit dataChanged(); + return true; + } + return false; } bool Component::isCustom() { - return m_file != nullptr; + return m_file != nullptr; } bool Component::isCustomizable() { - if(m_metaVersion) - { - if(getVersionFile()) - { - return true; - } - } - return false; + if(m_metaVersion) + { + if(getVersionFile()) + { + return true; + } + } + return false; } bool Component::isRemovable() { - return !m_important; + return !m_important; } bool Component::isRevertible() { - if (isCustom()) - { - if(ENV.metadataIndex()->hasUid(m_uid)) - { - return true; - } - } - return false; + if (isCustom()) + { + if(ENV.metadataIndex()->hasUid(m_uid)) + { + return true; + } + } + return false; } bool Component::isMoveable() { - // HACK, FIXME: this was too dumb and wouldn't follow dependency constraints anyway. For now hardcoded to 'true'. - return true; + // HACK, FIXME: this was too dumb and wouldn't follow dependency constraints anyway. For now hardcoded to 'true'. + return true; } bool Component::isVersionChangeable() { - auto list = getVersionList(); - if(list) - { - if(!list->isLoaded()) - { - list->load(Net::Mode::Online); - } - return list->count() != 0; - } - return false; + auto list = getVersionList(); + if(list) + { + if(!list->isLoaded()) + { + list->load(Net::Mode::Online); + } + return list->count() != 0; + } + return false; } void Component::setImportant(bool state) { - if(m_important != state) - { - m_important = state; - emit dataChanged(); - } + if(m_important != state) + { + m_important = state; + emit dataChanged(); + } } ProblemSeverity Component::getProblemSeverity() const { - auto file = getVersionFile(); - if(file) - { - return file->getProblemSeverity(); - } - return ProblemSeverity::Error; + auto file = getVersionFile(); + if(file) + { + return file->getProblemSeverity(); + } + return ProblemSeverity::Error; } const QList Component::getProblems() const { - auto file = getVersionFile(); - if(file) - { - return file->getProblems(); - } - return {{ProblemSeverity::Error, QObject::tr("Patch is not loaded yet.")}}; + auto file = getVersionFile(); + if(file) + { + return file->getProblems(); + } + return {{ProblemSeverity::Error, QObject::tr("Patch is not loaded yet.")}}; } void Component::setVersion(const QString& version) { - if(version == m_version) - { - return; - } - m_version = version; - if(m_loaded) - { - // we are loaded and potentially have state to invalidate - if(m_file) - { - // we have a file... explicit version has been changed and there is nothing else to do. - } - else - { - // we don't have a file, therefore we are loaded with metadata - m_cachedVersion = version; - // see if the meta version is loaded - auto metaVersion = ENV.metadataIndex()->get(m_uid, version); - if(metaVersion->isLoaded()) - { - // if yes, we can continue with that. - m_metaVersion = metaVersion; - } - else - { - // if not, we need loading - m_metaVersion.reset(); - m_loaded = false; - } - updateCachedData(); - } - } - else - { - // not loaded... assume it will be sorted out later by the update task - } - emit dataChanged(); + if(version == m_version) + { + return; + } + m_version = version; + if(m_loaded) + { + // we are loaded and potentially have state to invalidate + if(m_file) + { + // we have a file... explicit version has been changed and there is nothing else to do. + } + else + { + // we don't have a file, therefore we are loaded with metadata + m_cachedVersion = version; + // see if the meta version is loaded + auto metaVersion = ENV.metadataIndex()->get(m_uid, version); + if(metaVersion->isLoaded()) + { + // if yes, we can continue with that. + m_metaVersion = metaVersion; + } + else + { + // if not, we need loading + m_metaVersion.reset(); + m_loaded = false; + } + updateCachedData(); + } + } + else + { + // not loaded... assume it will be sorted out later by the update task + } + emit dataChanged(); } bool Component::customize() { - if(isCustom()) - { - return false; - } + if(isCustom()) + { + return false; + } - auto filename = getFilename(); - 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 = getVersionFile(); - if(!vfile) - { - return false; - } - auto document = OneSixVersionFormat::versionFileToJson(vfile); - jsonFile.write(document.toJson()); - if(!jsonFile.commit()) - { - return false; - } - m_file = vfile; - m_metaVersion.reset(); - emit dataChanged(); - } - catch (const Exception &error) - { - qWarning() << "Version could not be loaded:" << error.cause(); - } - return true; + auto filename = getFilename(); + 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 = getVersionFile(); + if(!vfile) + { + return false; + } + auto document = OneSixVersionFormat::versionFileToJson(vfile); + jsonFile.write(document.toJson()); + if(!jsonFile.commit()) + { + return false; + } + m_file = vfile; + m_metaVersion.reset(); + emit dataChanged(); + } + catch (const Exception &error) + { + qWarning() << "Version could not be loaded:" << error.cause(); + } + return true; } bool Component::revert() { - if(!isCustom()) - { - // already not custom - return true; - } - auto filename = getFilename(); - bool result = true; - // just kill the file and reload - if(QFile::exists(filename)) - { - result = QFile::remove(filename); - } - if(result) - { - // file gone... - m_file.reset(); + if(!isCustom()) + { + // already not custom + return true; + } + auto filename = getFilename(); + bool result = true; + // just kill the file and reload + if(QFile::exists(filename)) + { + result = QFile::remove(filename); + } + if(result) + { + // file gone... + m_file.reset(); - // check local cache for metadata... - auto version = ENV.metadataIndex()->get(m_uid, m_version); - if(version->isLoaded()) - { - m_metaVersion = version; - } - else - { - m_metaVersion.reset(); - m_loaded = false; - } - emit dataChanged(); - } - return result; + // check local cache for metadata... + auto version = ENV.metadataIndex()->get(m_uid, m_version); + if(version->isLoaded()) + { + m_metaVersion = version; + } + else + { + m_metaVersion.reset(); + m_loaded = false; + } + emit dataChanged(); + } + return result; } /** @@ -372,68 +372,68 @@ bool Component::revert() */ static bool deepCompare(const std::set & a, const std::set & b) { - // NOTE: this needs to be rewritten if the type of Meta::RequireSet changes - if(a.size() != b.size()) - { - return false; - } - for(const auto & reqA :a) - { - const auto &iter2 = b.find(reqA); - if(iter2 == b.cend()) - { - return false; - } - const auto & reqB = *iter2; - if(!reqA.deepEquals(reqB)) - { - return false; - } - } - return true; + // NOTE: this needs to be rewritten if the type of Meta::RequireSet changes + if(a.size() != b.size()) + { + return false; + } + for(const auto & reqA :a) + { + const auto &iter2 = b.find(reqA); + if(iter2 == b.cend()) + { + return false; + } + const auto & reqB = *iter2; + if(!reqA.deepEquals(reqB)) + { + return false; + } + } + return true; } void Component::updateCachedData() { - auto file = getVersionFile(); - if(file) - { - bool changed = false; - if(m_cachedName != file->name) - { - m_cachedName = file->name; - changed = true; - } - if(m_cachedVersion != file->version) - { - m_cachedVersion = file->version; - changed = true; - } - if(m_cachedVolatile != file->m_volatile) - { - m_cachedVolatile = file->m_volatile; - changed = true; - } - if(!deepCompare(m_cachedRequires, file->requires)) - { - m_cachedRequires = file->requires; - changed = true; - } - if(!deepCompare(m_cachedConflicts, file->conflicts)) - { - m_cachedConflicts = file->conflicts; - changed = true; - } - if(changed) - { - emit dataChanged(); - } - } - else - { - // in case we removed all the metadata - m_cachedRequires.clear(); - m_cachedConflicts.clear(); - emit dataChanged(); - } + auto file = getVersionFile(); + if(file) + { + bool changed = false; + if(m_cachedName != file->name) + { + m_cachedName = file->name; + changed = true; + } + if(m_cachedVersion != file->version) + { + m_cachedVersion = file->version; + changed = true; + } + if(m_cachedVolatile != file->m_volatile) + { + m_cachedVolatile = file->m_volatile; + changed = true; + } + if(!deepCompare(m_cachedRequires, file->requires)) + { + m_cachedRequires = file->requires; + changed = true; + } + if(!deepCompare(m_cachedConflicts, file->conflicts)) + { + m_cachedConflicts = file->conflicts; + changed = true; + } + if(changed) + { + emit dataChanged(); + } + } + else + { + // in case we removed all the metadata + m_cachedRequires.clear(); + m_cachedConflicts.clear(); + emit dataChanged(); + } } diff --git a/api/logic/minecraft/Component.h b/api/logic/minecraft/Component.h index 778fbb18..6a0f86c8 100644 --- a/api/logic/minecraft/Component.h +++ b/api/logic/minecraft/Component.h @@ -13,8 +13,8 @@ class ComponentList; class LaunchProfile; namespace Meta { - class Version; - class VersionList; + class Version; + class VersionList; } class VersionFile; @@ -22,90 +22,90 @@ class MULTIMC_LOGIC_EXPORT Component : public QObject, public ProblemProvider { Q_OBJECT public: - Component(ComponentList * parent, const QString &uid); + Component(ComponentList * parent, const QString &uid); - // DEPRECATED: remove these constructors? - Component(ComponentList * parent, std::shared_ptr version); - Component(ComponentList * parent, const QString & uid, std::shared_ptr file); + // DEPRECATED: remove these constructors? + Component(ComponentList * parent, std::shared_ptr version); + Component(ComponentList * parent, const QString & uid, std::shared_ptr file); - virtual ~Component(){}; - void applyTo(LaunchProfile *profile); + virtual ~Component(){}; + void applyTo(LaunchProfile *profile); - bool isEnabled(); - bool setEnabled (bool state); - bool canBeDisabled(); + bool isEnabled(); + bool setEnabled (bool state); + bool canBeDisabled(); - bool isMoveable(); - bool isCustomizable(); - bool isRevertible(); - bool isRemovable(); - bool isCustom(); - bool isVersionChangeable(); + bool isMoveable(); + bool isCustomizable(); + bool isRevertible(); + bool isRemovable(); + bool isCustom(); + bool isVersionChangeable(); - // DEPRECATED: explicit numeric order values, used for loading old non-component config. TODO: refactor and move to migration code - void setOrder(int order); - int getOrder(); + // DEPRECATED: explicit numeric order values, used for loading old non-component config. TODO: refactor and move to migration code + void setOrder(int order); + int getOrder(); - QString getID(); - QString getName(); - QString getVersion(); - std::shared_ptr getMeta(); - QDateTime getReleaseDateTime(); + QString getID(); + QString getName(); + QString getVersion(); + std::shared_ptr getMeta(); + QDateTime getReleaseDateTime(); - QString getFilename(); + QString getFilename(); - std::shared_ptr getVersionFile() const; - std::shared_ptr getVersionList() const; + std::shared_ptr getVersionFile() const; + std::shared_ptr getVersionList() const; - void setImportant (bool state); + void setImportant (bool state); - const QList getProblems() const override; - ProblemSeverity getProblemSeverity() const override; + const QList getProblems() const override; + ProblemSeverity getProblemSeverity() const override; - void setVersion(const QString & version); - bool customize(); - bool revert(); + void setVersion(const QString & version); + bool customize(); + bool revert(); - void updateCachedData(); + void updateCachedData(); signals: - void dataChanged(); + void dataChanged(); public: /* data */ - ComponentList * m_parent; - - // BEGIN: persistent component list properties - /// ID of the component - QString m_uid; - /// version of the component - when there's a custom json override, this is also the version the component reverts to - QString m_version; - /// if true, this has been added automatically to satisfy dependencies and may be automatically removed - bool m_dependencyOnly = false; - /// if true, the component is either the main component of the instance, or otherwise important and cannot be removed. - bool m_important = false; - /// if true, the component is disabled - bool m_disabled = false; - - /// cached name for display purposes, taken from the version file (meta or local override) - QString m_cachedName; - /// cached version for display AND other purposes, taken from the version file (meta or local override) - QString m_cachedVersion; - /// cached set of requirements, taken from the version file (meta or local override) - Meta::RequireSet m_cachedRequires; - Meta::RequireSet m_cachedConflicts; - /// if true, the component is volatile and may be automatically removed when no longer needed - bool m_cachedVolatile = false; - // END: persistent component list properties - - // DEPRECATED: explicit numeric order values, used for loading old non-component config. TODO: refactor and move to migration code - bool m_orderOverride = false; - int m_order = 0; - - // load state - std::shared_ptr m_metaVersion; - std::shared_ptr m_file; - bool m_loaded = false; + ComponentList * m_parent; + + // BEGIN: persistent component list properties + /// ID of the component + QString m_uid; + /// version of the component - when there's a custom json override, this is also the version the component reverts to + QString m_version; + /// if true, this has been added automatically to satisfy dependencies and may be automatically removed + bool m_dependencyOnly = false; + /// if true, the component is either the main component of the instance, or otherwise important and cannot be removed. + bool m_important = false; + /// if true, the component is disabled + bool m_disabled = false; + + /// cached name for display purposes, taken from the version file (meta or local override) + QString m_cachedName; + /// cached version for display AND other purposes, taken from the version file (meta or local override) + QString m_cachedVersion; + /// cached set of requirements, taken from the version file (meta or local override) + Meta::RequireSet m_cachedRequires; + Meta::RequireSet m_cachedConflicts; + /// if true, the component is volatile and may be automatically removed when no longer needed + bool m_cachedVolatile = false; + // END: persistent component list properties + + // DEPRECATED: explicit numeric order values, used for loading old non-component config. TODO: refactor and move to migration code + bool m_orderOverride = false; + int m_order = 0; + + // load state + std::shared_ptr m_metaVersion; + std::shared_ptr m_file; + bool m_loaded = false; }; typedef shared_qobject_ptr ComponentPtr; diff --git a/api/logic/minecraft/ComponentList.cpp b/api/logic/minecraft/ComponentList.cpp index e373d499..7a865c60 100644 --- a/api/logic/minecraft/ComponentList.cpp +++ b/api/logic/minecraft/ComponentList.cpp @@ -37,18 +37,18 @@ #include "ComponentUpdateTask.h" ComponentList::ComponentList(MinecraftInstance * instance) - : QAbstractListModel() + : QAbstractListModel() { - d.reset(new ComponentListData); - d->m_instance = instance; - d->m_saveTimer.setSingleShot(true); - d->m_saveTimer.setInterval(5000); - connect(&d->m_saveTimer, &QTimer::timeout, this, &ComponentList::save_internal); + d.reset(new ComponentListData); + d->m_instance = instance; + d->m_saveTimer.setSingleShot(true); + d->m_saveTimer.setInterval(5000); + connect(&d->m_saveTimer, &QTimer::timeout, this, &ComponentList::save_internal); } ComponentList::~ComponentList() { - saveNow(); + saveNow(); } // BEGIN: component file format @@ -57,151 +57,151 @@ static const int currentComponentsFileVersion = 1; static QJsonObject componentToJsonV1(ComponentPtr component) { - QJsonObject obj; - // critical - obj.insert("uid", component->m_uid); - if(!component->m_version.isEmpty()) - { - obj.insert("version", component->m_version); - } - if(component->m_dependencyOnly) - { - obj.insert("dependencyOnly", true); - } - if(component->m_important) - { - obj.insert("important", true); - } - if(component->m_disabled) - { - obj.insert("disabled", true); - } - - // cached - if(!component->m_cachedVersion.isEmpty()) - { - obj.insert("cachedVersion", component->m_cachedVersion); - } - 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) - { - obj.insert("cachedVolatile", true); - } - return obj; + QJsonObject obj; + // critical + obj.insert("uid", component->m_uid); + if(!component->m_version.isEmpty()) + { + obj.insert("version", component->m_version); + } + if(component->m_dependencyOnly) + { + obj.insert("dependencyOnly", true); + } + if(component->m_important) + { + obj.insert("important", true); + } + if(component->m_disabled) + { + obj.insert("disabled", true); + } + + // cached + if(!component->m_cachedVersion.isEmpty()) + { + obj.insert("cachedVersion", component->m_cachedVersion); + } + 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) + { + obj.insert("cachedVolatile", true); + } + return obj; } static ComponentPtr componentFromJsonV1(ComponentList * parent, const QString & componentJsonPattern, const QJsonObject &obj) { - // critical - auto uid = Json::requireString(obj.value("uid")); - auto filePath = componentJsonPattern.arg(uid); - auto component = new Component(parent, uid); - component->m_version = Json::ensureString(obj.value("version")); - component->m_dependencyOnly = Json::ensureBoolean(obj.value("dependencyOnly"), false); - component->m_important = Json::ensureBoolean(obj.value("important"), false); - - // cached - // TODO @RESILIENCE: ignore invalid values/structure here? - component->m_cachedVersion = Json::ensureString(obj.value("cachedVersion")); - component->m_cachedName = Json::ensureString(obj.value("cachedName")); - Meta::parseRequires(obj, &component->m_cachedRequires, "cachedRequires"); - Meta::parseRequires(obj, &component->m_cachedConflicts, "cachedConflicts"); - component->m_cachedVolatile = Json::ensureBoolean(obj.value("volatile"), false); - bool disabled = Json::ensureBoolean(obj.value("disabled"), false); - component->setEnabled(!disabled); - return component; + // critical + auto uid = Json::requireString(obj.value("uid")); + auto filePath = componentJsonPattern.arg(uid); + auto component = new Component(parent, uid); + component->m_version = Json::ensureString(obj.value("version")); + component->m_dependencyOnly = Json::ensureBoolean(obj.value("dependencyOnly"), false); + component->m_important = Json::ensureBoolean(obj.value("important"), false); + + // cached + // TODO @RESILIENCE: ignore invalid values/structure here? + component->m_cachedVersion = Json::ensureString(obj.value("cachedVersion")); + component->m_cachedName = Json::ensureString(obj.value("cachedName")); + Meta::parseRequires(obj, &component->m_cachedRequires, "cachedRequires"); + Meta::parseRequires(obj, &component->m_cachedConflicts, "cachedConflicts"); + component->m_cachedVolatile = Json::ensureBoolean(obj.value("volatile"), false); + bool disabled = Json::ensureBoolean(obj.value("disabled"), false); + component->setEnabled(!disabled); + return component; } // Save the given component container data to a file static bool saveComponentList(const QString & filename, const ComponentContainer & container) { - QJsonObject obj; - obj.insert("formatVersion", currentComponentsFileVersion); - QJsonArray orderArray; - 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(); - 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(); - return false; - } - if(!outFile.commit()) - { - qCritical() << "Couldn't save" << outFile.fileName() - << "because:" << outFile.errorString(); - } - return true; + QJsonObject obj; + obj.insert("formatVersion", currentComponentsFileVersion); + QJsonArray orderArray; + 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(); + 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(); + return false; + } + if(!outFile.commit()) + { + qCritical() << "Couldn't save" << outFile.fileName() + << "because:" << outFile.errorString(); + } + return true; } // Read the given file into component containers static bool loadComponentList(ComponentList * parent, const QString & filename, const QString & componentJsonPattern, ComponentContainer & container) { - QFile componentsFile(filename); - 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(); - qWarning() << "Ignoring overriden order"; - return false; - } - - // and it's valid JSON - QJsonParseError error; - QJsonDocument doc = QJsonDocument::fromJson(componentsFile.readAll(), &error); - 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 - { - 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)); - } - auto orderArray = Json::requireArray(obj.value("components")); - for(auto item: orderArray) - { - auto obj = Json::requireObject(item, "Component must be an object."); - container.append(componentFromJsonV1(parent, componentJsonPattern, obj)); - } - } - catch (const JSONValidationError &err) - { - qCritical() << "Couldn't parse" << componentsFile.fileName() << ": bad file format"; - container.clear(); - return false; - } - return true; + QFile componentsFile(filename); + 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(); + qWarning() << "Ignoring overriden order"; + return false; + } + + // and it's valid JSON + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(componentsFile.readAll(), &error); + 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 + { + 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)); + } + auto orderArray = Json::requireArray(obj.value("components")); + for(auto item: orderArray) + { + auto obj = Json::requireObject(item, "Component must be an object."); + container.append(componentFromJsonV1(parent, componentJsonPattern, obj)); + } + } + catch (const JSONValidationError &err) + { + qCritical() << "Couldn't parse" << componentsFile.fileName() << ": bad file format"; + container.clear(); + return false; + } + return true; } // END: component file format @@ -210,217 +210,217 @@ static bool loadComponentList(ComponentList * parent, const QString & filename, void ComponentList::saveNow() { - if(saveIsScheduled()) - { - d->m_saveTimer.stop(); - save_internal(); - } + if(saveIsScheduled()) + { + d->m_saveTimer.stop(); + save_internal(); + } } bool ComponentList::saveIsScheduled() const { - return d->dirty; + return d->dirty; } void ComponentList::buildingFromScratch() { - d->loaded = true; - d->dirty = true; + d->loaded = true; + d->dirty = true; } void ComponentList::scheduleSave() { - if(!d->loaded) - { - qDebug() << "Component list should never save if it didn't successfully load, instance:" << d->m_instance->name(); - return; - } - if(!d->dirty) - { - d->dirty = true; - qDebug() << "Component list save is scheduled for" << d->m_instance->name(); - } - d->m_saveTimer.start(); + if(!d->loaded) + { + qDebug() << "Component list should never save if it didn't successfully load, instance:" << d->m_instance->name(); + return; + } + if(!d->dirty) + { + d->dirty = true; + qDebug() << "Component list save is scheduled for" << d->m_instance->name(); + } + d->m_saveTimer.start(); } QString ComponentList::componentsFilePath() const { - return FS::PathCombine(d->m_instance->instanceRoot(), "mmc-pack.json"); + return FS::PathCombine(d->m_instance->instanceRoot(), "mmc-pack.json"); } QString ComponentList::patchesPattern() const { - return FS::PathCombine(d->m_instance->instanceRoot(), "patches", "%1.json"); + return FS::PathCombine(d->m_instance->instanceRoot(), "patches", "%1.json"); } QString ComponentList::patchFilePathForUid(const QString& uid) const { - return patchesPattern().arg(uid); + return patchesPattern().arg(uid); } void ComponentList::save_internal() { - qDebug() << "Component list save performed now for" << d->m_instance->name(); - auto filename = componentsFilePath(); - saveComponentList(filename, d->components); - d->dirty = false; + qDebug() << "Component list save performed now for" << d->m_instance->name(); + auto filename = componentsFilePath(); + saveComponentList(filename, d->components); + d->dirty = false; } bool ComponentList::load() { - auto filename = componentsFilePath(); - QFile componentsFile(filename); - - // migrate old config to new one, if needed - if(!componentsFile.exists()) - { - if(!migratePreComponentConfig()) - { - // FIXME: the user should be notified... - qCritical() << "Failed to convert old pre-component config for instance" << d->m_instance->name(); - return false; - } - } - - // load the new component list and swap it with the current one... - ComponentContainer newComponents; - if(!loadComponentList(this, filename, patchesPattern(), newComponents)) - { - qCritical() << "Failed to load the component config for instance" << d->m_instance->name(); - return false; - } - else - { - // FIXME: actually use fine-grained updates, not this... - beginResetModel(); - // disconnect all the old components - for(auto component: d->components) - { - disconnect(component.get(), &Component::dataChanged, this, &ComponentList::componentDataChanged); - } - d->components.clear(); - d->componentIndex.clear(); - for(auto component: newComponents) - { - if(d->componentIndex.contains(component->m_uid)) - { - qWarning() << "Ignoring duplicate component entry" << component->m_uid; - continue; - } - connect(component.get(), &Component::dataChanged, this, &ComponentList::componentDataChanged); - d->components.append(component); - d->componentIndex[component->m_uid] = component; - } - endResetModel(); - d->loaded = true; - return true; - } + auto filename = componentsFilePath(); + QFile componentsFile(filename); + + // migrate old config to new one, if needed + if(!componentsFile.exists()) + { + if(!migratePreComponentConfig()) + { + // FIXME: the user should be notified... + qCritical() << "Failed to convert old pre-component config for instance" << d->m_instance->name(); + return false; + } + } + + // load the new component list and swap it with the current one... + ComponentContainer newComponents; + if(!loadComponentList(this, filename, patchesPattern(), newComponents)) + { + qCritical() << "Failed to load the component config for instance" << d->m_instance->name(); + return false; + } + else + { + // FIXME: actually use fine-grained updates, not this... + beginResetModel(); + // disconnect all the old components + for(auto component: d->components) + { + disconnect(component.get(), &Component::dataChanged, this, &ComponentList::componentDataChanged); + } + d->components.clear(); + d->componentIndex.clear(); + for(auto component: newComponents) + { + if(d->componentIndex.contains(component->m_uid)) + { + qWarning() << "Ignoring duplicate component entry" << component->m_uid; + continue; + } + connect(component.get(), &Component::dataChanged, this, &ComponentList::componentDataChanged); + d->components.append(component); + d->componentIndex[component->m_uid] = component; + } + endResetModel(); + d->loaded = true; + return true; + } } void ComponentList::reload(Net::Mode netmode) { - // Do not reload when the update/resolve task is running. It is in control. - if(d->m_updateTask) - { - return; - } - - // flush any scheduled saves to not lose state - saveNow(); - - // FIXME: differentiate when a reapply is required by propagating state from components - invalidateLaunchProfile(); - - if(load()) - { - resolve(netmode); - } + // Do not reload when the update/resolve task is running. It is in control. + if(d->m_updateTask) + { + return; + } + + // flush any scheduled saves to not lose state + saveNow(); + + // FIXME: differentiate when a reapply is required by propagating state from components + invalidateLaunchProfile(); + + if(load()) + { + resolve(netmode); + } } shared_qobject_ptr ComponentList::getCurrentTask() { - return d->m_updateTask; + return d->m_updateTask; } void ComponentList::resolve(Net::Mode netmode) { - auto updateTask = new ComponentUpdateTask(ComponentUpdateTask::Mode::Resolution, netmode, this); - d->m_updateTask.reset(updateTask); - connect(updateTask, &ComponentUpdateTask::succeeded, this, &ComponentList::updateSucceeded); - connect(updateTask, &ComponentUpdateTask::failed, this, &ComponentList::updateFailed); - d->m_updateTask->start(); + auto updateTask = new ComponentUpdateTask(ComponentUpdateTask::Mode::Resolution, netmode, this); + d->m_updateTask.reset(updateTask); + connect(updateTask, &ComponentUpdateTask::succeeded, this, &ComponentList::updateSucceeded); + connect(updateTask, &ComponentUpdateTask::failed, this, &ComponentList::updateFailed); + d->m_updateTask->start(); } void ComponentList::updateSucceeded() { - qDebug() << "Component list update/resolve task succeeded for" << d->m_instance->name(); - d->m_updateTask.reset(); - invalidateLaunchProfile(); + qDebug() << "Component list update/resolve task succeeded for" << d->m_instance->name(); + d->m_updateTask.reset(); + invalidateLaunchProfile(); } void ComponentList::updateFailed(const QString& error) { - qDebug() << "Component list update/resolve task failed for" << d->m_instance->name() << "Reason:" << error; - d->m_updateTask.reset(); - invalidateLaunchProfile(); + qDebug() << "Component list update/resolve task failed for" << d->m_instance->name() << "Reason:" << error; + d->m_updateTask.reset(); + invalidateLaunchProfile(); } // NOTE this is really old stuff, and only needs to be used when loading the old hardcoded component-unaware format (loadPreComponentConfig). static void upgradeDeprecatedFiles(QString root, QString instanceName) { - auto versionJsonPath = FS::PathCombine(root, "version.json"); - auto customJsonPath = FS::PathCombine(root, "custom.json"); - auto mcJson = FS::PathCombine(root, "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" << instanceName; - return; - } - if(!renameFile.isEmpty() && QFile::exists(renameFile)) - { - if(!QFile::rename(renameFile, renameFile + ".old")) - { - qWarning() << "Couldn't rename" << renameFile << "to" << renameFile + ".old" << "in" << instanceName; - return; - } - } - auto file = ProfileUtils::parseJsonFile(QFileInfo(sourceFile), false); - ProfileUtils::removeLwjglFromPatch(file); - file->uid = "net.minecraft"; - file->version = file->minecraftVersion; - file->name = "Minecraft"; - - Meta::Require needsLwjgl; - needsLwjgl.uid = "org.lwjgl"; - file->requires.insert(needsLwjgl); - - if(!ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), mcJson)) - { - return; - } - if(!QFile::rename(sourceFile, sourceFile + ".old")) - { - qWarning() << "Couldn't rename" << sourceFile << "to" << sourceFile + ".old" << "in" << instanceName; - return; - } - } + auto versionJsonPath = FS::PathCombine(root, "version.json"); + auto customJsonPath = FS::PathCombine(root, "custom.json"); + auto mcJson = FS::PathCombine(root, "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" << instanceName; + return; + } + if(!renameFile.isEmpty() && QFile::exists(renameFile)) + { + if(!QFile::rename(renameFile, renameFile + ".old")) + { + qWarning() << "Couldn't rename" << renameFile << "to" << renameFile + ".old" << "in" << instanceName; + return; + } + } + auto file = ProfileUtils::parseJsonFile(QFileInfo(sourceFile), false); + ProfileUtils::removeLwjglFromPatch(file); + file->uid = "net.minecraft"; + file->version = file->minecraftVersion; + file->name = "Minecraft"; + + Meta::Require needsLwjgl; + needsLwjgl.uid = "org.lwjgl"; + file->requires.insert(needsLwjgl); + + if(!ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), mcJson)) + { + return; + } + if(!QFile::rename(sourceFile, sourceFile + ".old")) + { + qWarning() << "Couldn't rename" << sourceFile << "to" << sourceFile + ".old" << "in" << instanceName; + return; + } + } } /* @@ -431,774 +431,774 @@ static void upgradeDeprecatedFiles(QString root, QString instanceName) */ bool ComponentList::migratePreComponentConfig() { - // upgrade the very old files from the beginnings of MultiMC 5 - upgradeDeprecatedFiles(d->m_instance->instanceRoot(), d->m_instance->name()); - - QList components; - QSet loaded; - - auto addBuiltinPatch = [&](const QString &uid, bool asDependency, const QString & emptyVersion, const Meta::Require & req, const Meta::Require & conflict) - { - auto jsonFilePath = FS::PathCombine(d->m_instance->instanceRoot(), "patches" , uid + ".json"); - auto intendedVersion = d->getOldConfigVersion(uid); - // load up the base minecraft patch - ComponentPtr component; - if(QFile::exists(jsonFilePath)) - { - if(intendedVersion.isEmpty()) - { - intendedVersion = emptyVersion; - } - auto file = ProfileUtils::parseJsonFile(QFileInfo(jsonFilePath), false); - // fix uid - file->uid = uid; - // if version is missing, add it from the outside. - if(file->version.isEmpty()) - { - file->version = intendedVersion; - } - // if this is a dependency (LWJGL), mark it also as volatile - if(asDependency) - { - file->m_volatile = true; - } - // insert requirements if needed - if(!req.uid.isEmpty()) - { - file->requires.insert(req); - } - // insert conflicts if needed - if(!conflict.uid.isEmpty()) - { - file->conflicts.insert(conflict); - } - // FIXME: @QUALITY do not ignore return value - ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), jsonFilePath); - component = new Component(this, uid, file); - component->m_version = intendedVersion; - } - else if(!intendedVersion.isEmpty()) - { - auto metaVersion = ENV.metadataIndex()->get(uid, intendedVersion); - component = new Component(this, metaVersion); - } - else - { - return; - } - component->m_dependencyOnly = asDependency; - component->m_important = !asDependency; - components.append(component); - }; - // TODO: insert depends and conflicts here if these are customized files... - Meta::Require reqLwjgl; - reqLwjgl.uid = "org.lwjgl"; - reqLwjgl.suggests = "2.9.1"; - Meta::Require conflictLwjgl3; - conflictLwjgl3.uid = "org.lwjgl3"; - Meta::Require nullReq; - addBuiltinPatch("org.lwjgl", true, "2.9.1