diff options
-rw-r--r-- | api/logic/minecraft/onesix/OneSixInstance.cpp | 32 | ||||
-rw-r--r-- | api/logic/minecraft/onesix/OneSixProfileStrategy.cpp | 143 | ||||
-rw-r--r-- | application/pages/VersionPage.cpp | 10 |
3 files changed, 103 insertions, 82 deletions
diff --git a/api/logic/minecraft/onesix/OneSixInstance.cpp b/api/logic/minecraft/onesix/OneSixInstance.cpp index d89f6f87..4a4380a4 100644 --- a/api/logic/minecraft/onesix/OneSixInstance.cpp +++ b/api/logic/minecraft/onesix/OneSixInstance.cpp @@ -34,8 +34,15 @@ OneSixInstance::OneSixInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) : MinecraftInstance(globalSettings, settings, rootDir) { + // set explicitly during instance creation m_settings->registerSetting({"IntendedVersion", "MinecraftVersion"}, ""); - m_settings->registerSetting("LWJGLVersion", ""); + + // defaults to the version we've been using for years (2.9.1) + m_settings->registerSetting("LWJGLVersion", "2.9.1"); + + // optionals + m_settings->registerSetting("ForgeVersion", ""); + m_settings->registerSetting("LiteloaderVersion", ""); } void OneSixInstance::init() @@ -499,6 +506,14 @@ bool OneSixInstance::setComponentVersion(const QString& uid, const QString& vers { settings()->set("LWJGLVersion", version); } + else if (uid == "net.minecraftforge") + { + settings()->set("ForgeVersion", version); + } + else if (uid == "com.liteloader") + { + settings()->set("LiteloaderVersion", version); + } if(getMinecraftProfile()) { clearProfile(); @@ -515,12 +530,15 @@ QString OneSixInstance::getComponentVersion(const QString& uid) const } else if(uid == "org.lwjgl") { - auto version = settings()->get("LWJGLVersion").toString(); - if(version.isEmpty()) - { - return "2.9.1"; - } - return version; + return settings()->get("LWJGLVersion").toString(); + } + else if(uid == "net.minecraftforge") + { + return settings()->get("ForgeVersion").toString(); + } + else if(uid == "com.liteloader") + { + return settings()->get("LiteloaderVersion").toString(); } return QString(); } diff --git a/api/logic/minecraft/onesix/OneSixProfileStrategy.cpp b/api/logic/minecraft/onesix/OneSixProfileStrategy.cpp index 4a56a810..e08dd529 100644 --- a/api/logic/minecraft/onesix/OneSixProfileStrategy.cpp +++ b/api/logic/minecraft/onesix/OneSixProfileStrategy.cpp @@ -120,99 +120,93 @@ void OneSixProfileStrategy::loadDefaultBuiltinPatches() void OneSixProfileStrategy::loadUserPatches() { - // load all patches, put into map for ordering, apply in the right order - ProfileUtils::PatchOrder userOrder; - ProfileUtils::readOverrideOrders(FS::PathCombine(m_instance->instanceRoot(), "order.json"), userOrder); - QDir patches(FS::PathCombine(m_instance->instanceRoot(),"patches")); - QSet<QString> seen_extra; - - // first, load things by sort order. - for (auto id : userOrder) + // 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 (id == "net.minecraft") + if (file->uid == "net.minecraft") continue; - if (id == "org.lwjgl") + if (file->uid == "org.lwjgl") continue; - // parse the file - QString filename = patches.absoluteFilePath(id + ".json"); - QFileInfo finfo(filename); - if(!finfo.exists()) + auto patch = std::make_shared<ProfilePatch>(file, info.filePath()); + patch->setRemovable(true); + patch->setMovable(true); + if(ENV.metadataIndex()->hasUid(file->uid)) { - qDebug() << "Patch file " << filename << " was deleted by external means..."; - continue; + // FIXME: requesting a uid/list creates it in the index... this allows reverting to possibly invalid versions... + patch->setRevertible(true); } - qDebug() << "Reading" << filename << "by user order"; - VersionFilePtr file = ProfileUtils::parseJsonFile(finfo, false); - // sanity check. prevent tampering with files. - if (file->uid != id) + 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)) { - file->addProblem(ProblemSeverity::Warning, QObject::tr("load id %1 does not match internal id %2").arg(id, file->uid)); - seen_extra.insert(file->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; } - auto patchEntry = std::make_shared<ProfilePatch>(file, filename); - patchEntry->setRemovable(true); - patchEntry->setMovable(true); - profile->appendPatch(patchEntry); - } - // now load the rest by internal preference. - using FileEntry = std::tuple<VersionFilePtr, QString>; - QMultiMap<int, FileEntry> files; - for (auto info : patches.entryInfoList(QStringList() << "*.json", QDir::Files)) + }; + loadSpecial("net.minecraftforge", 5); + loadSpecial("com.liteloader", 10); + + // now add all the patches by user sort order + ProfileUtils::PatchOrder userOrder; + ProfileUtils::readOverrideOrders(FS::PathCombine(m_instance->instanceRoot(), "order.json"), userOrder); + bool orderIsDirty = false; + for (auto uid : userOrder) { - // 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") + if (uid == "net.minecraft") continue; - // do not load versions with broken IDs twice - if(seen_extra.contains(file->uid)) + if (uid == "org.lwjgl") continue; - // do not load what we already loaded in the first pass - if (userOrder.contains(file->uid)) + // ordering has a patch that is gone? + if(!loadedPatches.contains(uid)) + { + orderIsDirty = true; continue; - files.insert(file->order, std::make_tuple(file, info.filePath())); + } + profile->appendPatch(loadedPatches.take(uid)); } - auto appendFilePatch = [&](FileEntry tuple) + + // is there anything left to sort? + if(loadedPatches.isEmpty()) { - VersionFilePtr file; - QString filename; - std::tie(file, filename) = tuple; - auto patchEntry = std::make_shared<ProfilePatch>(file, filename); - patchEntry->setRemovable(true); - patchEntry->setMovable(true); - profile->appendPatch(patchEntry); - }; - QSet<int> seen; + // 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()) { - if(seen.contains(order)) - continue; - seen.insert(order); const auto &values = files.values(order); - if(values.size() == 1) - { - appendFilePatch(values[0]); - continue; - } - for(auto &file: values) + for(auto &value: values) { - QStringList list; - for(auto &file2: values) - { - if(file != file2) - { - list.append(std::get<0>(file2)->name); - } - } - auto vfileptr = std::get<0>(file); - vfileptr->addProblem(ProblemSeverity::Warning, QObject::tr("%1 has the same order as the following components:\n%2").arg(vfileptr->name, list.join(", "))); - appendFilePatch(file); + // TODO: put back the insertion of problem messages here, so the user knows about the id duplication + profile->appendPatch(value); } } + // TODO: save the order here? } @@ -249,7 +243,10 @@ bool OneSixProfileStrategy::removePatch(ProfilePatchPtr patch) return false; } } - + if(!m_instance->getComponentVersion(patch->getID()).isEmpty()) + { + m_instance->setComponentVersion(patch->getID(), QString()); + } auto preRemoveJarMod = [&](JarmodPtr jarMod) -> bool { diff --git a/application/pages/VersionPage.cpp b/application/pages/VersionPage.cpp index 94068786..a7029b36 100644 --- a/application/pages/VersionPage.cpp +++ b/application/pages/VersionPage.cpp @@ -401,7 +401,10 @@ void VersionPage::on_forgeBtn_clicked() vselect.setEmptyErrorString(tr("Couldn't load or download the Forge version lists!")); if (vselect.exec() && vselect.selectedVersion()) { - m_profile->installVersion(vselect.selectedVersion()); + auto vsn = vselect.selectedVersion(); + m_inst->setComponentVersion("net.minecraftforge", vsn->descriptor()); + m_profile->reload(); + // m_profile->installVersion(); preselect(m_profile->rowCount(QModelIndex())-1); m_container->refreshContainer(); } @@ -420,7 +423,10 @@ void VersionPage::on_liteloaderBtn_clicked() vselect.setEmptyErrorString(tr("Couldn't load or download the LiteLoader version lists!")); if (vselect.exec() && vselect.selectedVersion()) { - m_profile->installVersion(vselect.selectedVersion()); + auto vsn = vselect.selectedVersion(); + m_inst->setComponentVersion("com.liteloader", vsn->descriptor()); + m_profile->reload(); + // m_profile->installVersion(vselect.selectedVersion()); preselect(m_profile->rowCount(QModelIndex())-1); m_container->refreshContainer(); } |