summaryrefslogtreecommitdiffstats
path: root/logic/OneSixUpdate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'logic/OneSixUpdate.cpp')
-rw-r--r--logic/OneSixUpdate.cpp445
1 files changed, 0 insertions, 445 deletions
diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp
deleted file mode 100644
index 5ec36305..00000000
--- a/logic/OneSixUpdate.cpp
+++ /dev/null
@@ -1,445 +0,0 @@
-/* Copyright 2013-2015 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 "logic/Env.h"
-#include "OneSixUpdate.h"
-
-#include <QtNetwork>
-
-#include <QFile>
-#include <QFileInfo>
-#include <QTextStream>
-#include <QDataStream>
-#include <pathutils.h>
-#include <JlCompress.h>
-
-#include "logic/BaseInstance.h"
-#include "logic/minecraft/MinecraftVersionList.h"
-#include "logic/minecraft/MinecraftProfile.h"
-#include "logic/minecraft/OneSixLibrary.h"
-#include "logic/OneSixInstance.h"
-#include "logic/forge/ForgeMirrors.h"
-#include "logic/net/URLConstants.h"
-#include "logic/assets/AssetsUtils.h"
-#include "JarUtils.h"
-
-OneSixUpdate::OneSixUpdate(OneSixInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
-{
-}
-
-void OneSixUpdate::executeTask()
-{
- // Make directories
- QDir mcDir(m_inst->minecraftRoot());
- if (!mcDir.exists() && !mcDir.mkpath("."))
- {
- emitFailed(tr("Failed to create folder for minecraft binaries."));
- return;
- }
-
- // Get a pointer to the version object that corresponds to the instance's version.
- targetVersion = std::dynamic_pointer_cast<MinecraftVersion>(
- ENV.getVersion("net.minecraft", m_inst->intendedVersionId()));
- if (targetVersion == nullptr)
- {
- // don't do anything if it was invalid
- emitFailed(tr("The specified Minecraft version is invalid. Choose a different one."));
- return;
- }
- if (m_inst->providesVersionFile() || !targetVersion->needsUpdate())
- {
- qDebug() << "Instance either provides a version file or doesn't need an update.";
- jarlibStart();
- return;
- }
- versionUpdateTask = std::dynamic_pointer_cast<MinecraftVersionList>(ENV.getVersionList("net.minecraft"))->createUpdateTask(m_inst->intendedVersionId());
- if (!versionUpdateTask)
- {
- qDebug() << "Didn't spawn an update task.";
- jarlibStart();
- return;
- }
- connect(versionUpdateTask.get(), SIGNAL(succeeded()), SLOT(jarlibStart()));
- connect(versionUpdateTask.get(), SIGNAL(failed(QString)), SLOT(versionUpdateFailed(QString)));
- connect(versionUpdateTask.get(), SIGNAL(progress(qint64, qint64)),
- SIGNAL(progress(qint64, qint64)));
- setStatus(tr("Getting the version files from Mojang..."));
- versionUpdateTask->start();
-}
-
-void OneSixUpdate::versionUpdateFailed(QString reason)
-{
- emitFailed(reason);
-}
-
-void OneSixUpdate::assetIndexStart()
-{
- setStatus(tr("Updating assets index..."));
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- std::shared_ptr<MinecraftProfile> version = inst->getMinecraftProfile();
- QString assetName = version->assets;
- QUrl indexUrl = "http://" + URLConstants::AWS_DOWNLOAD_INDEXES + assetName + ".json";
- QString localPath = assetName + ".json";
- auto job = new NetJob(tr("Asset index for %1").arg(inst->name()));
-
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("asset_indexes", localPath);
- job->addNetAction(CacheDownload::make(indexUrl, entry));
- jarlibDownloadJob.reset(job);
-
- connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(assetIndexFinished()));
- connect(jarlibDownloadJob.get(), SIGNAL(failed()), SLOT(assetIndexFailed()));
- connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)),
- SIGNAL(progress(qint64, qint64)));
-
- jarlibDownloadJob->start();
-}
-
-void OneSixUpdate::assetIndexFinished()
-{
- AssetsIndex index;
-
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- std::shared_ptr<MinecraftProfile> version = inst->getMinecraftProfile();
- QString assetName = version->assets;
-
- QString asset_fname = "assets/indexes/" + assetName + ".json";
- if (!AssetsUtils::loadAssetsIndexJson(asset_fname, &index))
- {
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("asset_indexes", assetName + ".json");
- metacache->evictEntry(entry);
- emitFailed(tr("Failed to read the assets index!"));
- }
-
- QList<Md5EtagDownloadPtr> dls;
- for (auto object : index.objects.values())
- {
- QString objectName = object.hash.left(2) + "/" + object.hash;
- QFileInfo objectFile("assets/objects/" + objectName);
- if ((!objectFile.isFile()) || (objectFile.size() != object.size))
- {
- auto objectDL = MD5EtagDownload::make(
- QUrl("http://" + URLConstants::RESOURCE_BASE + objectName),
- objectFile.filePath());
- objectDL->m_total_progress = object.size;
- dls.append(objectDL);
- }
- }
- if (dls.size())
- {
- setStatus(tr("Getting the assets files from Mojang..."));
- auto job = new NetJob(tr("Assets for %1").arg(inst->name()));
- for (auto dl : dls)
- job->addNetAction(dl);
- jarlibDownloadJob.reset(job);
- connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(assetsFinished()));
- connect(jarlibDownloadJob.get(), SIGNAL(failed()), SLOT(assetsFailed()));
- connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)),
- SIGNAL(progress(qint64, qint64)));
- jarlibDownloadJob->start();
- return;
- }
- assetsFinished();
-}
-
-void OneSixUpdate::assetIndexFailed()
-{
- emitFailed(tr("Failed to download the assets index!"));
-}
-
-void OneSixUpdate::assetsFinished()
-{
- emitSucceeded();
-}
-
-void OneSixUpdate::assetsFailed()
-{
- emitFailed(tr("Failed to download assets!"));
-}
-
-void OneSixUpdate::jarlibStart()
-{
- setStatus(tr("Getting the library files from Mojang..."));
- qDebug() << m_inst->name() << ": downloading libraries";
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- try
- {
- inst->reloadProfile();
- }
- catch (MMCError &e)
- {
- emitFailed(e.cause());
- return;
- }
- catch (...)
- {
- emitFailed(tr("Failed to load the version description file for reasons unknown."));
- return;
- }
-
- // Build a list of URLs that will need to be downloaded.
- std::shared_ptr<MinecraftProfile> version = inst->getMinecraftProfile();
- // minecraft.jar for this version
- {
- QString version_id = version->id;
- QString localPath = version_id + "/" + version_id + ".jar";
- QString urlstr = "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + localPath;
-
- auto job = new NetJob(tr("Libraries for instance %1").arg(inst->name()));
-
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("versions", localPath);
- job->addNetAction(CacheDownload::make(QUrl(urlstr), entry));
- jarHashOnEntry = entry->md5sum;
-
- jarlibDownloadJob.reset(job);
- }
-
- auto libs = version->getActiveNativeLibs();
- libs.append(version->getActiveNormalLibs());
-
- auto metacache = ENV.metacache();
- QList<ForgeXzDownloadPtr> ForgeLibs;
- QList<std::shared_ptr<OneSixLibrary>> brokenLocalLibs;
-
- for (auto lib : libs)
- {
- if (lib->hint() == "local")
- {
- if (!lib->filesExist(m_inst->librariesPath()))
- brokenLocalLibs.append(lib);
- continue;
- }
-
- QString raw_storage = lib->storagePath();
- QString raw_dl = lib->downloadUrl();
-
- auto f = [&](QString storage, QString dl)
- {
- auto entry = metacache->resolveEntry("libraries", storage);
- if (entry->stale)
- {
- if (lib->hint() == "forge-pack-xz")
- {
- ForgeLibs.append(ForgeXzDownload::make(storage, entry));
- }
- else
- {
- jarlibDownloadJob->addNetAction(CacheDownload::make(dl, entry));
- }
- }
- };
- if (raw_storage.contains("${arch}"))
- {
- QString cooked_storage = raw_storage;
- QString cooked_dl = raw_dl;
- f(cooked_storage.replace("${arch}", "32"), cooked_dl.replace("${arch}", "32"));
- cooked_storage = raw_storage;
- cooked_dl = raw_dl;
- f(cooked_storage.replace("${arch}", "64"), cooked_dl.replace("${arch}", "64"));
- }
- else
- {
- f(raw_storage, raw_dl);
- }
- }
- if (!brokenLocalLibs.empty())
- {
- jarlibDownloadJob.reset();
- QStringList failed;
- for (auto brokenLib : brokenLocalLibs)
- {
- failed.append(brokenLib->files());
- }
- QString failed_all = failed.join("\n");
- emitFailed(tr("Some libraries marked as 'local' are missing their jar "
- "files:\n%1\n\nYou'll have to correct this problem manually. If this is "
- "an externally tracked instance, make sure to run it at least once "
- "outside of MultiMC.").arg(failed_all));
- return;
- }
- // TODO: think about how to propagate this from the original json file... or IF AT ALL
- QString forgeMirrorList = "http://files.minecraftforge.net/mirror-brand.list";
- if (!ForgeLibs.empty())
- {
- jarlibDownloadJob->addNetAction(
- ForgeMirrors::make(ForgeLibs, jarlibDownloadJob, forgeMirrorList));
- }
-
- connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(jarlibFinished()));
- connect(jarlibDownloadJob.get(), SIGNAL(failed()), SLOT(jarlibFailed()));
- connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)),
- SIGNAL(progress(qint64, qint64)));
-
- jarlibDownloadJob->start();
-}
-
-void OneSixUpdate::jarlibFinished()
-{
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- std::shared_ptr<MinecraftProfile> version = inst->getMinecraftProfile();
-
- // nuke obsolete stripped jar(s) if needed
- QString version_id = version->id;
- QString strippedPath = version_id + "/" + version_id + "-stripped.jar";
- QFile strippedJar(strippedPath);
- if(strippedJar.exists())
- {
- strippedJar.remove();
- }
- auto finalJarPath = QDir(m_inst->instanceRoot()).absoluteFilePath("temp.jar");
- QFile finalJar(finalJarPath);
- if(finalJar.exists())
- {
- if(!finalJar.remove())
- {
- emitFailed(tr("Couldn't remove stale jar file: %1").arg(finalJarPath));
- return;
- }
- }
-
- // create temporary modded jar, if needed
- auto jarMods = inst->getJarMods();
- if(jarMods.size())
- {
- auto sourceJarPath = m_inst->versionsPath().absoluteFilePath(version->id + "/" + version->id + ".jar");
- QString localPath = version_id + "/" + version_id + ".jar";
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("versions", localPath);
- QString fullJarPath = entry->getFullPath();
- if(!JarUtils::createModdedJar(sourceJarPath, finalJarPath, jarMods))
- {
- emitFailed(tr("Failed to create the custom Minecraft jar file."));
- return;
- }
- }
- if (version->traits.contains("legacyFML"))
- {
- fmllibsStart();
- }
- else
- {
- assetIndexStart();
- }
-}
-
-void OneSixUpdate::jarlibFailed()
-{
- QStringList failed = jarlibDownloadJob->getFailedFiles();
- QString failed_all = failed.join("\n");
- emitFailed(
- tr("Failed to download the following files:\n%1\n\nPlease try again.").arg(failed_all));
-}
-
-void OneSixUpdate::fmllibsStart()
-{
- // Get the mod list
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- std::shared_ptr<MinecraftProfile> fullversion = inst->getMinecraftProfile();
- bool forge_present = false;
-
- QString version = inst->intendedVersionId();
- auto &fmlLibsMapping = g_VersionFilterData.fmlLibsMapping;
- if (!fmlLibsMapping.contains(version))
- {
- assetIndexStart();
- return;
- }
-
- auto &libList = fmlLibsMapping[version];
-
- // determine if we need some libs for FML or forge
- setStatus(tr("Checking for FML libraries..."));
- forge_present = (fullversion->versionPatch("net.minecraftforge") != nullptr);
- // we don't...
- if (!forge_present)
- {
- assetIndexStart();
- return;
- }
-
- // now check the lib folder inside the instance for files.
- for (auto &lib : libList)
- {
- QFileInfo libInfo(PathCombine(inst->libDir(), lib.filename));
- if (libInfo.exists())
- continue;
- fmlLibsToProcess.append(lib);
- }
-
- // if everything is in place, there's nothing to do here...
- if (fmlLibsToProcess.isEmpty())
- {
- assetIndexStart();
- return;
- }
-
- // download missing libs to our place
- setStatus(tr("Dowloading FML libraries..."));
- auto dljob = new NetJob("FML libraries");
- auto metacache = ENV.metacache();
- for (auto &lib : fmlLibsToProcess)
- {
- auto entry = metacache->resolveEntry("fmllibs", lib.filename);
- QString urlString = lib.ours ? URLConstants::FMLLIBS_OUR_BASE_URL + lib.filename
- : URLConstants::FMLLIBS_FORGE_BASE_URL + lib.filename;
- dljob->addNetAction(CacheDownload::make(QUrl(urlString), entry));
- }
-
- connect(dljob, SIGNAL(succeeded()), SLOT(fmllibsFinished()));
- connect(dljob, SIGNAL(failed()), SLOT(fmllibsFailed()));
- connect(dljob, SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- legacyDownloadJob.reset(dljob);
- legacyDownloadJob->start();
-}
-
-void OneSixUpdate::fmllibsFinished()
-{
- legacyDownloadJob.reset();
- if (!fmlLibsToProcess.isEmpty())
- {
- setStatus(tr("Copying FML libraries into the instance..."));
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- auto metacache = ENV.metacache();
- int index = 0;
- for (auto &lib : fmlLibsToProcess)
- {
- progress(index, fmlLibsToProcess.size());
- auto entry = metacache->resolveEntry("fmllibs", lib.filename);
- auto path = PathCombine(inst->libDir(), lib.filename);
- if (!ensureFilePathExists(path))
- {
- emitFailed(tr("Failed creating FML library folder inside the instance."));
- return;
- }
- if (!QFile::copy(entry->getFullPath(), PathCombine(inst->libDir(), lib.filename)))
- {
- emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename));
- return;
- }
- index++;
- }
- progress(index, fmlLibsToProcess.size());
- }
- assetIndexStart();
-}
-
-void OneSixUpdate::fmllibsFailed()
-{
- emitFailed("Game update failed: it was impossible to fetch the required FML libraries.");
- return;
-}
-