summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt11
-rw-r--r--MultiMC.cpp3
-rw-r--r--gui/MainWindow.cpp11
-rw-r--r--gui/MainWindow.h2
-rw-r--r--logic/LegacyUpdate.cpp2
-rw-r--r--logic/OneSixAssets.cpp127
-rw-r--r--logic/OneSixAssets.h45
-rw-r--r--logic/OneSixInstance.cpp5
-rw-r--r--logic/OneSixUpdate.cpp99
-rw-r--r--logic/OneSixUpdate.h7
-rw-r--r--logic/assets/Assets.cpp14
-rw-r--r--logic/assets/Assets.h16
-rw-r--r--logic/assets/AssetsIndex.cpp31
-rw-r--r--logic/assets/AssetsIndex.h42
-rw-r--r--logic/assets/AssetsUtils.cpp121
-rw-r--r--logic/assets/AssetsUtils.h17
-rw-r--r--logic/net/MD5EtagDownload.cpp (renamed from logic/net/FileDownload.cpp)17
-rw-r--r--logic/net/MD5EtagDownload.h (renamed from logic/net/FileDownload.h)10
-rw-r--r--logic/net/NetJob.cpp2
-rw-r--r--logic/net/NetJob.h2
20 files changed, 203 insertions, 381 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2c27ca81..7df7967f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -284,8 +284,8 @@ logic/InstanceLauncher.cpp
# network stuffs
logic/net/NetAction.h
-logic/net/FileDownload.h
-logic/net/FileDownload.cpp
+logic/net/MD5EtagDownload.h
+logic/net/MD5EtagDownload.cpp
logic/net/ByteArrayDownload.h
logic/net/ByteArrayDownload.cpp
logic/net/CacheDownload.h
@@ -325,8 +325,6 @@ logic/LegacyForge.h
logic/LegacyForge.cpp
# 1.6 instances
-logic/OneSixAssets.h
-logic/OneSixAssets.cpp
logic/OneSixInstance.h
logic/OneSixInstance.cpp
logic/OneSixInstance_p.h
@@ -385,13 +383,8 @@ logic/SkinUtils.h
logic/SkinUtils.cpp
# Assets
-logic/assets/AssetsIndex.h
-logic/assets/AssetsIndex.cpp
logic/assets/AssetsUtils.h
logic/assets/AssetsUtils.cpp
-logic/assets/Assets.h
-logic/assets/Assets.cpp
-
)
diff --git a/MultiMC.cpp b/MultiMC.cpp
index e10292ab..1057c5d3 100644
--- a/MultiMC.cpp
+++ b/MultiMC.cpp
@@ -351,7 +351,8 @@ void MultiMC::initGlobalSettings()
void MultiMC::initHttpMetaCache()
{
m_metacache.reset(new HttpMetaCache("metacache"));
- m_metacache->addBase("assets", QDir("assets").absolutePath());
+ m_metacache->addBase("asset_indexes", QDir("assets/indexes").absolutePath());
+ m_metacache->addBase("asset_objects", QDir("assets/objects").absolutePath());
m_metacache->addBase("versions", QDir("versions").absolutePath());
m_metacache->addBase("libraries", QDir("libraries").absolutePath());
m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath());
diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp
index b080f610..d8ba5572 100644
--- a/gui/MainWindow.cpp
+++ b/gui/MainWindow.cpp
@@ -72,7 +72,6 @@
#include "logic/BaseInstance.h"
#include "logic/InstanceFactory.h"
#include "logic/MinecraftProcess.h"
-#include "logic/OneSixAssets.h"
#include "logic/OneSixUpdate.h"
#include "logic/JavaUtils.h"
#include "logic/NagUtils.h"
@@ -233,15 +232,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
{
MMC->lwjgllist()->loadList();
}
-
- assets_downloader = new OneSixAssets();
- connect(assets_downloader, SIGNAL(indexStarted()), SLOT(assetsIndexStarted()));
- connect(assets_downloader, SIGNAL(filesStarted()), SLOT(assetsFilesStarted()));
- connect(assets_downloader, SIGNAL(filesProgress(int, int, int)),
- SLOT(assetsFilesProgress(int, int, int)));
- connect(assets_downloader, SIGNAL(failed()), SLOT(assetsFailed()));
- connect(assets_downloader, SIGNAL(finished()), SLOT(assetsFinished()));
- //assets_downloader->start();
}
const QString currentInstanceId = MMC->settings()->get("SelectedInstance").toString();
@@ -274,7 +264,6 @@ MainWindow::~MainWindow()
delete ui;
delete proxymodel;
delete drawer;
- delete assets_downloader;
}
void MainWindow::repopulateAccountsMenu()
diff --git a/gui/MainWindow.h b/gui/MainWindow.h
index 62c9797e..795590c0 100644
--- a/gui/MainWindow.h
+++ b/gui/MainWindow.h
@@ -31,7 +31,6 @@ class KCategorizedView;
class KCategoryDrawer;
class MinecraftProcess;
class ConsoleWindow;
-class OneSixAssets;
namespace Ui
{
@@ -173,7 +172,6 @@ private:
InstanceProxyModel *proxymodel;
MinecraftProcess *proc;
ConsoleWindow *console;
- OneSixAssets *assets_downloader;
LabeledToolButton *renameButton;
QToolButton *changeIconButton;
diff --git a/logic/LegacyUpdate.cpp b/logic/LegacyUpdate.cpp
index 6125101b..fa3fd240 100644
--- a/logic/LegacyUpdate.cpp
+++ b/logic/LegacyUpdate.cpp
@@ -266,7 +266,7 @@ void LegacyUpdate::jarStart()
urlstr += intended_version_id + "/" + intended_version_id + ".jar";
auto dljob = new NetJob("Minecraft.jar for version " + intended_version_id);
- dljob->addNetAction(FileDownload::make(QUrl(urlstr), inst->defaultBaseJar()));
+ dljob->addNetAction(MD5EtagDownload::make(QUrl(urlstr), inst->defaultBaseJar()));
legacyDownloadJob.reset(dljob);
connect(dljob, SIGNAL(succeeded()), SLOT(jarFinished()));
connect(dljob, SIGNAL(failed()), SLOT(jarFailed()));
diff --git a/logic/OneSixAssets.cpp b/logic/OneSixAssets.cpp
deleted file mode 100644
index 400aff2c..00000000
--- a/logic/OneSixAssets.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/* Copyright 2013 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 <QString>
-#include "logger/QsLog.h"
-#include <QtXml/QtXml>
-#include "OneSixAssets.h"
-#include "net/NetJob.h"
-#include "net/HttpMetaCache.h"
-#include "net/S3ListBucket.h"
-#include "MultiMC.h"
-
-#define ASSETS_URL "http://resources.download.minecraft.net/"
-
-class ThreadedDeleter : public QThread
-{
- Q_OBJECT
-public:
- void run()
- {
- QLOG_INFO() << "Cleaning up assets folder...";
- QDirIterator iter(m_base, QDirIterator::Subdirectories);
- int base_length = m_base.length();
- while (iter.hasNext())
- {
- QString filename = iter.next();
- QFileInfo current(filename);
- // we keep the dirs... whatever
- if (current.isDir())
- continue;
- QString trimmedf = filename;
- trimmedf.remove(0, base_length + 1);
- if (m_whitelist.contains(trimmedf))
- {
- QLOG_TRACE() << trimmedf << " gets to live";
- }
- else
- {
- // DO NOT TOLERATE JUNK
- QLOG_TRACE() << trimmedf << " dies";
- QFile f(filename);
- f.remove();
- }
- }
- }
- QString m_base;
- QStringList m_whitelist;
-};
-
-void OneSixAssets::downloadFinished()
-{
- deleter = new ThreadedDeleter();
- QDir dir("assets");
- deleter->m_base = dir.absolutePath();
- deleter->m_whitelist = nuke_whitelist;
- connect(deleter, SIGNAL(finished()), SIGNAL(finished()));
- deleter->start();
-}
-
-void OneSixAssets::S3BucketFinished()
-{
- QString prefix(ASSETS_URL);
- nuke_whitelist.clear();
-
- emit filesStarted();
-
- auto firstJob = index_job->first();
- auto objectList = std::dynamic_pointer_cast<S3ListBucket>(firstJob)->objects;
-
- NetJob *job = new NetJob("Assets");
-
- connect(job, SIGNAL(succeeded()), SLOT(downloadFinished()));
- connect(job, SIGNAL(failed()), SIGNAL(failed()));
- connect(job, SIGNAL(filesProgress(int, int, int)), SIGNAL(filesProgress(int, int, int)));
-
- auto metacache = MMC->metacache();
-
- for (auto object : objectList)
- {
- // Filter folder keys (zero size)
- if (object.size == 0)
- continue;
-
- nuke_whitelist.append(object.Key);
-
- auto entry = metacache->resolveEntry("assets", object.Key, object.ETag);
- if (entry->stale)
- {
- job->addNetAction(CacheDownload::make(QUrl(prefix + object.Key), entry));
- }
- }
- if (job->size())
- {
- files_job.reset(job);
- files_job->start();
- }
- else
- {
- delete job;
- emit finished();
- }
-}
-
-void OneSixAssets::start()
-{
- auto job = new NetJob("Assets index");
- job->addNetAction(S3ListBucket::make(QUrl(ASSETS_URL)));
- connect(job, SIGNAL(succeeded()), SLOT(S3BucketFinished()));
- connect(job, SIGNAL(failed()), SIGNAL(failed()));
- emit indexStarted();
- index_job.reset(job);
- job->start();
-}
-
-#include "OneSixAssets.moc"
diff --git a/logic/OneSixAssets.h b/logic/OneSixAssets.h
deleted file mode 100644
index 948068b8..00000000
--- a/logic/OneSixAssets.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright 2013 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.
- */
-
-#pragma once
-#include "net/NetJob.h"
-
-class Private;
-class ThreadedDeleter;
-
-class OneSixAssets : public QObject
-{
- Q_OBJECT
-signals:
- void failed();
- void finished();
- void indexStarted();
- void filesStarted();
- void filesProgress(int, int, int);
-
-public
-slots:
- void S3BucketFinished();
- void downloadFinished();
-
-public:
- void start();
-
-private:
- ThreadedDeleter *deleter;
- QStringList nuke_whitelist;
- NetJobPtr index_job;
- NetJobPtr files_job;
-};
diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp
index e804de11..b8d85ff5 100644
--- a/logic/OneSixInstance.cpp
+++ b/logic/OneSixInstance.cpp
@@ -26,7 +26,6 @@
#include <JlCompress.h>
#include "gui/dialogs/OneSixModEditDialog.h"
#include "logger/QsLog.h"
-#include "logic/assets/AssetsIndex.h"
#include "logic/assets/AssetsUtils.h"
OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_obj,
@@ -96,9 +95,9 @@ QDir OneSixInstance::reconstructAssets(std::shared_ptr<OneSixVersion> version)
{
QLOG_INFO() << "Reconstructing virtual assets folder at" << virtualRoot.path();
- for(QString map : index.objects->keys())
+ for(QString map : index.objects.keys())
{
- AssetObject asset_object = index.objects->value(map);
+ AssetObject asset_object = index.objects.value(map);
QString target_path = PathCombine(virtualRoot.path(), map);
QFile target(target_path);
diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp
index 7be0c056..97876e5c 100644
--- a/logic/OneSixUpdate.cpp
+++ b/logic/OneSixUpdate.cpp
@@ -29,6 +29,7 @@
#include "OneSixLibrary.h"
#include "OneSixInstance.h"
#include "net/ForgeMirrors.h"
+#include "assets/AssetsUtils.h"
#include "pathutils.h"
#include <JlCompress.h>
@@ -50,7 +51,7 @@ void OneSixUpdate::executeTask()
return;
}
- if(m_only_prepare)
+ if (m_only_prepare)
{
if (m_inst->shouldUpdate())
{
@@ -93,7 +94,7 @@ void OneSixUpdate::checkJavaOnline()
checker.reset(new JavaChecker());
connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this,
- SLOT(checkFinishedOnline(JavaCheckResult)));
+ SLOT(checkFinishedOnline(JavaCheckResult)));
checker->performCheck(java_path);
}
@@ -193,6 +194,96 @@ void OneSixUpdate::versionFileFailed()
emitFailed("Failed to download the version description. Try again.");
}
+void OneSixUpdate::assetIndexStart()
+{
+ setStatus("Updating asset index.");
+ OneSixInstance *inst = (OneSixInstance *)m_inst;
+ std::shared_ptr<OneSixVersion> version = inst->getFullVersion();
+ QString assetName = version->assets;
+ QUrl indexUrl("https://s3.amazonaws.com/Minecraft.Download/indexes/" + assetName + ".json");
+ QString localPath = assetName + ".json";
+ auto job = new NetJob("Asset index for " + inst->name());
+
+ auto metacache = MMC->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<OneSixVersion> version = inst->getFullVersion();
+ QString assetName = version->assets;
+
+ QString asset_fname = "assets/indexes/" + assetName + ".json";
+ if (!AssetsUtils::loadAssetsIndexJson(asset_fname, &index))
+ {
+ emitFailed("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://resources.download.minecraft.net/" + objectName),
+ objectFile.filePath());
+ dls.append(objectDL);
+ /*
+ Downloadable downloadable = new AssetDownloadable(
+ proxy, new URL("http://resources.download.minecraft.net/" + filename), file,
+ false, object.getHash(), object.getSize());
+ downloadable.setExpectedSize(object.getSize());
+ result.add(downloadable);
+ */
+ }
+ }
+ if(dls.size())
+ {
+ auto job = new NetJob("Assets for " + 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("Failed to download the assets index!");
+}
+
+void OneSixUpdate::assetsFinished()
+{
+ prepareForLaunch();
+}
+
+void OneSixUpdate::assetsFailed()
+{
+ emitFailed("Failed to download assets!");
+}
+
+
+
void OneSixUpdate::jarlibStart()
{
setStatus("Getting the library files from Mojang.");
@@ -215,7 +306,7 @@ void OneSixUpdate::jarlibStart()
targetstr += version->id + "/" + version->id + ".jar";
auto job = new NetJob("Libraries for instance " + inst->name());
- job->addNetAction(FileDownload::make(QUrl(urlstr), targetstr));
+ job->addNetAction(MD5EtagDownload::make(QUrl(urlstr), targetstr));
jarlibDownloadJob.reset(job);
auto libs = version->getActiveNativeLibs();
@@ -265,7 +356,7 @@ void OneSixUpdate::jarlibStart()
void OneSixUpdate::jarlibFinished()
{
- prepareForLaunch();
+ assetIndexStart();
}
void OneSixUpdate::jarlibFailed()
diff --git a/logic/OneSixUpdate.h b/logic/OneSixUpdate.h
index 7ff9d881..00b769c7 100644
--- a/logic/OneSixUpdate.h
+++ b/logic/OneSixUpdate.h
@@ -43,6 +43,13 @@ slots:
void jarlibFinished();
void jarlibFailed();
+ void assetIndexStart();
+ void assetIndexFinished();
+ void assetIndexFailed();
+
+ void assetsFinished();
+ void assetsFailed();
+
void checkJavaOnline();
void checkFinishedOnline(JavaCheckResult result);
void checkFinishedOffline(JavaCheckResult result);
diff --git a/logic/assets/Assets.cpp b/logic/assets/Assets.cpp
deleted file mode 100644
index a0764674..00000000
--- a/logic/assets/Assets.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Copyright 2013 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.
- */
diff --git a/logic/assets/Assets.h b/logic/assets/Assets.h
deleted file mode 100644
index 09998ff8..00000000
--- a/logic/assets/Assets.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Copyright 2013 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.
- */
-
-#pragma once
diff --git a/logic/assets/AssetsIndex.cpp b/logic/assets/AssetsIndex.cpp
deleted file mode 100644
index 509f1add..00000000
--- a/logic/assets/AssetsIndex.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright 2013 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 "AssetsIndex.h"
-
-AssetsIndex::AssetsIndex()
-{
- // TODO: leak?
- this->objects = new QMap<QString, AssetObject>();
- this->isVirtual = false;
-}
-
-AssetObject::AssetObject(QString hash, qint64 size) : hash(hash), size(size)
-{
-}
-
-AssetObject::AssetObject()
-{
-}
diff --git a/logic/assets/AssetsIndex.h b/logic/assets/AssetsIndex.h
deleted file mode 100644
index 09ef0d92..00000000
--- a/logic/assets/AssetsIndex.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright 2013 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.
- */
-
-#pragma once
-
-#include <QString>
-#include <QMap>
-
-class AssetObject;
-
-class AssetsIndex
-{
-public:
- QMap<QString, AssetObject> *objects;
- bool isVirtual;
-
- AssetsIndex();
-};
-
-class AssetObject
-{
-public:
- AssetObject(QString hash, qint64 size);
- AssetObject();
- bool equals(AssetObject* other);
- QString getHashCode();
-
- QString hash;
- qint64 size;
-};
diff --git a/logic/assets/AssetsUtils.cpp b/logic/assets/AssetsUtils.cpp
index 8d7d6f46..11d928cf 100644
--- a/logic/assets/AssetsUtils.cpp
+++ b/logic/assets/AssetsUtils.cpp
@@ -28,54 +28,64 @@ namespace AssetsUtils
void migrateOldAssets()
{
QDir assets_dir("assets");
- if(!assets_dir.exists()) return;
+ if (!assets_dir.exists())
+ return;
assets_dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
int base_length = assets_dir.path().length();
QList<QString> blacklist = {"indexes", "objects", "virtual"};
- if(!assets_dir.exists("objects")) assets_dir.mkdir("objects");
+ if (!assets_dir.exists("objects"))
+ assets_dir.mkdir("objects");
QDir objects_dir("assets/objects");
QDirIterator iterator(assets_dir, QDirIterator::Subdirectories);
int successes = 0;
int failures = 0;
- while (iterator.hasNext()) {
+ while (iterator.hasNext())
+ {
QString currentDir = iterator.next();
- currentDir = currentDir.remove(0, base_length+1);
+ currentDir = currentDir.remove(0, base_length + 1);
bool ignore = false;
- for(QString blacklisted : blacklist)
+ for (QString blacklisted : blacklist)
{
- if(currentDir.startsWith(blacklisted)) ignore = true;
+ if (currentDir.startsWith(blacklisted))
+ ignore = true;
}
- if (!iterator.fileInfo().isDir() && !ignore) {
+ if (!iterator.fileInfo().isDir() && !ignore)
+ {
QString filename = iterator.filePath();
QFile input(filename);
input.open(QIODevice::ReadOnly | QIODevice::WriteOnly);
- QString sha1sum = QCryptographicHash::hash(input.readAll(), QCryptographicHash::Sha1)
- .toHex()
- .constData();
+ QString sha1sum =
+ QCryptographicHash::hash(input.readAll(), QCryptographicHash::Sha1)
+ .toHex()
+ .constData();
- QString object_name = filename.remove(0, base_length+1);
+ QString object_name = filename.remove(0, base_length + 1);
QLOG_DEBUG() << "Processing" << object_name << ":" << sha1sum << input.size();
QString object_tlk = sha1sum.left(2);
QString object_tlk_dir = objects_dir.path() + "/" + object_tlk;
QDir tlk_dir(object_tlk_dir);
- if(!tlk_dir.exists()) objects_dir.mkdir(object_tlk);
+ if (!tlk_dir.exists())
+ objects_dir.mkdir(object_tlk);
QString new_filename = tlk_dir.path() + "/" + sha1sum;
QFile new_object(new_filename);
- if(!new_object.exists())
+ if (!new_object.exists())
{
bool rename_success = input.rename(new_filename);
- QLOG_DEBUG() << " Doesn't exist, copying to" << new_filename << ":" << QString::number(rename_success);
- if(rename_success) successes++;
- else failures++;
+ QLOG_DEBUG() << " Doesn't exist, copying to" << new_filename << ":"
+ << QString::number(rename_success);
+ if (rename_success)
+ successes++;
+ else
+ failures++;
}
else
{
@@ -85,26 +95,31 @@ void migrateOldAssets()
}
}
- if(successes + failures == 0) {
+ if (successes + failures == 0)
+ {
QLOG_DEBUG() << "No legacy assets needed importing.";
}
else
{
- QLOG_DEBUG() << "Finished copying legacy assets:" << successes << "successes and" << failures << "failures.";
+ QLOG_DEBUG() << "Finished copying legacy assets:" << successes << "successes and"
+ << failures << "failures.";
QDirIterator cleanup_iterator(assets_dir);
- while (cleanup_iterator.hasNext()) {
+ while (cleanup_iterator.hasNext())
+ {
QString currentDir = cleanup_iterator.next();
- currentDir = currentDir.remove(0, base_length+1);
+ currentDir = currentDir.remove(0, base_length + 1);
bool ignore = false;
- for(QString blacklisted : blacklist)
+ for (QString blacklisted : blacklist)
{
- if(currentDir.startsWith(blacklisted)) ignore = true;
+ if (currentDir.startsWith(blacklisted))
+ ignore = true;
}
- if (cleanup_iterator.fileInfo().isDir() && !ignore) {
+ if (cleanup_iterator.fileInfo().isDir() && !ignore)
+ {
QString path = cleanup_iterator.filePath();
QDir folder(path);
@@ -122,18 +137,18 @@ void migrateOldAssets()
*/
bool loadAssetsIndexJson(QString path, AssetsIndex *index)
{
-/*
-{
- "objects": {
- "icons/icon_16x16.png": {
- "hash": "bdf48ef6b5d0d23bbb02e17d04865216179f510a",
- "size": 3665
- },
- ...
+ /*
+ {
+ "objects": {
+ "icons/icon_16x16.png": {
+ "hash": "bdf48ef6b5d0d23bbb02e17d04865216179f510a",
+ "size": 3665
+ },
+ ...
+ }
+ }
}
- }
-}
-*/
+ */
QFile file(path);
@@ -155,7 +170,8 @@ bool loadAssetsIndexJson(QString path, AssetsIndex *index)
// Fail if the JSON is invalid.
if (parseError.error != QJsonParseError::NoError)
{
- QLOG_ERROR() << "Failed to parse assets index file:" << parseError.errorString() << "at offset " << QString::number(parseError.offset);
+ QLOG_ERROR() << "Failed to parse assets index file:" << parseError.errorString()
+ << "at offset " << QString::number(parseError.offset);
return false;
}
@@ -169,7 +185,7 @@ bool loadAssetsIndexJson(QString path, AssetsIndex *index)
QJsonObject root = jsonDoc.object();
QJsonValue isVirtual = root.value("virtual");
- if(!isVirtual.isUndefined())
+ if (!isVirtual.isUndefined())
{
index->isVirtual = isVirtual.toBool(false);
}
@@ -177,48 +193,35 @@ bool loadAssetsIndexJson(QString path, AssetsIndex *index)
QJsonValue objects = root.value("objects");
QVariantMap map = objects.toVariant().toMap();
- for(QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter) {
- //QLOG_DEBUG() << iter.key();
+ for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
+ {
+ // QLOG_DEBUG() << 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) {
- //QLOG_DEBUG() << nested_iter.key() << nested_iter.value().toString();
+ for (QVariantMap::const_iterator nested_iter = nested_objects.begin();
+ nested_iter != nested_objects.end(); ++nested_iter)
+ {
+ // QLOG_DEBUG() << nested_iter.key() << nested_iter.value().toString();
QString key = nested_iter.key();
QVariant value = nested_iter.value();
- if(key == "hash")
+ if (key == "hash")
{
object.hash = value.toString();
}
- else if(key == "size")
+ else if (key == "size")
{
object.size = value.toDouble();
}
}
- index->objects->insert(iter.key(), object);
+ index->objects.insert(iter.key(), object);
}
return true;
- /*for (QJsonValue accountVal : objects)
- {
- QJsonObject accountObj = accountVal.toObject();
- MojangAccountPtr account = MojangAccount::loadFromJson(accountObj);
- if (account.get() != nullptr)
- {
- connect(account.get(), SIGNAL(changed()), SLOT(accountChanged()));
- m_accounts.append(account);
- }
- else
- {
- QLOG_WARN() << "Failed to load an account.";
- }
- }*/
-
- //return false;
}
}
diff --git a/logic/assets/AssetsUtils.h b/logic/assets/AssetsUtils.h
index 88a3b0dc..5276d5a5 100644
--- a/logic/assets/AssetsUtils.h
+++ b/logic/assets/AssetsUtils.h
@@ -15,7 +15,22 @@
#pragma once
-#include "AssetsIndex.h"
+#include <QString>
+#include <QMap>
+
+class AssetObject;
+
+struct AssetObject
+{
+ QString hash;
+ qint64 size;
+};
+
+struct AssetsIndex
+{
+ QMap<QString, AssetObject> objects;
+ bool isVirtual = false;
+};
namespace AssetsUtils
{
diff --git a/logic/net/FileDownload.cpp b/logic/net/MD5EtagDownload.cpp
index 239af351..7b77bfbf 100644
--- a/logic/net/FileDownload.cpp
+++ b/logic/net/MD5EtagDownload.cpp
@@ -14,12 +14,12 @@
*/
#include "MultiMC.h"
-#include "FileDownload.h"
+#include "MD5EtagDownload.h"
#include <pathutils.h>
#include <QCryptographicHash>
#include "logger/QsLog.h"
-FileDownload::FileDownload(QUrl url, QString target_path) : NetAction()
+MD5EtagDownload::MD5EtagDownload(QUrl url, QString target_path) : NetAction()
{
m_url = url;
m_target_path = target_path;
@@ -27,7 +27,7 @@ FileDownload::FileDownload(QUrl url, QString target_path) : NetAction()
m_status = Job_NotStarted;
}
-void FileDownload::start()
+void MD5EtagDownload::start()
{
QString filename = m_target_path;
m_output_file.setFileName(filename);
@@ -58,7 +58,7 @@ void FileDownload::start()
return;
}
- QLOG_INFO() << "Downloading " << m_url.toString();
+ QLOG_INFO() << "Downloading " << m_url.toString() << " expecting " << m_expected_md5;
QNetworkRequest request(m_url);
request.setRawHeader(QString("If-None-Match").toLatin1(), m_expected_md5.toLatin1());
request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
@@ -75,19 +75,19 @@ void FileDownload::start()
connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead()));
}
-void FileDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
+void MD5EtagDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
emit progress(index_within_job, bytesReceived, bytesTotal);
}
-void FileDownload::downloadError(QNetworkReply::NetworkError error)
+void MD5EtagDownload::downloadError(QNetworkReply::NetworkError error)
{
// error happened during download.
// TODO: log the reason why
m_status = Job_Failed;
}
-void FileDownload::downloadFinished()
+void MD5EtagDownload::downloadFinished()
{
// if the download succeeded
if (m_status != Job_Failed)
@@ -96,6 +96,7 @@ void FileDownload::downloadFinished()
m_status = Job_Finished;
m_output_file.close();
+ QLOG_INFO() << "Finished " << m_url.toString() << " got " << m_reply->rawHeader("ETag").constData();
m_reply.reset();
emit succeeded(index_within_job);
return;
@@ -110,7 +111,7 @@ void FileDownload::downloadFinished()
}
}
-void FileDownload::downloadReadyRead()
+void MD5EtagDownload::downloadReadyRead()
{
if (!m_output_file.isOpen())
{
diff --git a/logic/net/FileDownload.h b/logic/net/MD5EtagDownload.h
index 58380e86..416ab9de 100644
--- a/logic/net/FileDownload.h
+++ b/logic/net/MD5EtagDownload.h
@@ -18,8 +18,8 @@
#include "NetAction.h"
#include <QFile>
-typedef std::shared_ptr<class FileDownload> FileDownloadPtr;
-class FileDownload : public NetAction
+typedef std::shared_ptr<class MD5EtagDownload> Md5EtagDownloadPtr;
+class MD5EtagDownload : public NetAction
{
Q_OBJECT
public:
@@ -35,10 +35,10 @@ public:
QFile m_output_file;
public:
- explicit FileDownload(QUrl url, QString target_path);
- static FileDownloadPtr make(QUrl url, QString target_path)
+ explicit MD5EtagDownload(QUrl url, QString target_path);
+ static Md5EtagDownloadPtr make(QUrl url, QString target_path)
{
- return FileDownloadPtr(new FileDownload(url, target_path));
+ return Md5EtagDownloadPtr(new MD5EtagDownload(url, target_path));
}
protected
slots:
diff --git a/logic/net/NetJob.cpp b/logic/net/NetJob.cpp
index 333cdcbf..8b79bc54 100644
--- a/logic/net/NetJob.cpp
+++ b/logic/net/NetJob.cpp
@@ -16,7 +16,7 @@
#include "NetJob.h"
#include "pathutils.h"
#include "MultiMC.h"
-#include "FileDownload.h"
+#include "MD5EtagDownload.h"
#include "ByteArrayDownload.h"
#include "CacheDownload.h"
diff --git a/logic/net/NetJob.h b/logic/net/NetJob.h
index a7027e10..6e2e7607 100644
--- a/logic/net/NetJob.h
+++ b/logic/net/NetJob.h
@@ -18,7 +18,7 @@
#include <QLabel>
#include "NetAction.h"
#include "ByteArrayDownload.h"
-#include "FileDownload.h"
+#include "MD5EtagDownload.h"
#include "CacheDownload.h"
#include "HttpMetaCache.h"
#include "ForgeXzDownload.h"