Finish assets update for 1.7.3
This commit is contained in:
parent
8db2e5db81
commit
3f5c46a1c4
@ -284,8 +284,8 @@ logic/InstanceLauncher.cpp
|
|||||||
|
|
||||||
# network stuffs
|
# network stuffs
|
||||||
logic/net/NetAction.h
|
logic/net/NetAction.h
|
||||||
logic/net/FileDownload.h
|
logic/net/MD5EtagDownload.h
|
||||||
logic/net/FileDownload.cpp
|
logic/net/MD5EtagDownload.cpp
|
||||||
logic/net/ByteArrayDownload.h
|
logic/net/ByteArrayDownload.h
|
||||||
logic/net/ByteArrayDownload.cpp
|
logic/net/ByteArrayDownload.cpp
|
||||||
logic/net/CacheDownload.h
|
logic/net/CacheDownload.h
|
||||||
@ -325,8 +325,6 @@ logic/LegacyForge.h
|
|||||||
logic/LegacyForge.cpp
|
logic/LegacyForge.cpp
|
||||||
|
|
||||||
# 1.6 instances
|
# 1.6 instances
|
||||||
logic/OneSixAssets.h
|
|
||||||
logic/OneSixAssets.cpp
|
|
||||||
logic/OneSixInstance.h
|
logic/OneSixInstance.h
|
||||||
logic/OneSixInstance.cpp
|
logic/OneSixInstance.cpp
|
||||||
logic/OneSixInstance_p.h
|
logic/OneSixInstance_p.h
|
||||||
@ -385,13 +383,8 @@ logic/SkinUtils.h
|
|||||||
logic/SkinUtils.cpp
|
logic/SkinUtils.cpp
|
||||||
|
|
||||||
# Assets
|
# Assets
|
||||||
logic/assets/AssetsIndex.h
|
|
||||||
logic/assets/AssetsIndex.cpp
|
|
||||||
logic/assets/AssetsUtils.h
|
logic/assets/AssetsUtils.h
|
||||||
logic/assets/AssetsUtils.cpp
|
logic/assets/AssetsUtils.cpp
|
||||||
logic/assets/Assets.h
|
|
||||||
logic/assets/Assets.cpp
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -351,7 +351,8 @@ void MultiMC::initGlobalSettings()
|
|||||||
void MultiMC::initHttpMetaCache()
|
void MultiMC::initHttpMetaCache()
|
||||||
{
|
{
|
||||||
m_metacache.reset(new HttpMetaCache("metacache"));
|
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("versions", QDir("versions").absolutePath());
|
||||||
m_metacache->addBase("libraries", QDir("libraries").absolutePath());
|
m_metacache->addBase("libraries", QDir("libraries").absolutePath());
|
||||||
m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath());
|
m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath());
|
||||||
|
@ -72,7 +72,6 @@
|
|||||||
#include "logic/BaseInstance.h"
|
#include "logic/BaseInstance.h"
|
||||||
#include "logic/InstanceFactory.h"
|
#include "logic/InstanceFactory.h"
|
||||||
#include "logic/MinecraftProcess.h"
|
#include "logic/MinecraftProcess.h"
|
||||||
#include "logic/OneSixAssets.h"
|
|
||||||
#include "logic/OneSixUpdate.h"
|
#include "logic/OneSixUpdate.h"
|
||||||
#include "logic/JavaUtils.h"
|
#include "logic/JavaUtils.h"
|
||||||
#include "logic/NagUtils.h"
|
#include "logic/NagUtils.h"
|
||||||
@ -233,15 +232,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||||||
{
|
{
|
||||||
MMC->lwjgllist()->loadList();
|
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();
|
const QString currentInstanceId = MMC->settings()->get("SelectedInstance").toString();
|
||||||
@ -274,7 +264,6 @@ MainWindow::~MainWindow()
|
|||||||
delete ui;
|
delete ui;
|
||||||
delete proxymodel;
|
delete proxymodel;
|
||||||
delete drawer;
|
delete drawer;
|
||||||
delete assets_downloader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::repopulateAccountsMenu()
|
void MainWindow::repopulateAccountsMenu()
|
||||||
|
@ -31,7 +31,6 @@ class KCategorizedView;
|
|||||||
class KCategoryDrawer;
|
class KCategoryDrawer;
|
||||||
class MinecraftProcess;
|
class MinecraftProcess;
|
||||||
class ConsoleWindow;
|
class ConsoleWindow;
|
||||||
class OneSixAssets;
|
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
@ -173,7 +172,6 @@ private:
|
|||||||
InstanceProxyModel *proxymodel;
|
InstanceProxyModel *proxymodel;
|
||||||
MinecraftProcess *proc;
|
MinecraftProcess *proc;
|
||||||
ConsoleWindow *console;
|
ConsoleWindow *console;
|
||||||
OneSixAssets *assets_downloader;
|
|
||||||
LabeledToolButton *renameButton;
|
LabeledToolButton *renameButton;
|
||||||
QToolButton *changeIconButton;
|
QToolButton *changeIconButton;
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ void LegacyUpdate::jarStart()
|
|||||||
urlstr += intended_version_id + "/" + intended_version_id + ".jar";
|
urlstr += intended_version_id + "/" + intended_version_id + ".jar";
|
||||||
|
|
||||||
auto dljob = new NetJob("Minecraft.jar for version " + intended_version_id);
|
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);
|
legacyDownloadJob.reset(dljob);
|
||||||
connect(dljob, SIGNAL(succeeded()), SLOT(jarFinished()));
|
connect(dljob, SIGNAL(succeeded()), SLOT(jarFinished()));
|
||||||
connect(dljob, SIGNAL(failed()), SLOT(jarFailed()));
|
connect(dljob, SIGNAL(failed()), SLOT(jarFailed()));
|
||||||
|
@ -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"
|
|
@ -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;
|
|
||||||
};
|
|
@ -26,7 +26,6 @@
|
|||||||
#include <JlCompress.h>
|
#include <JlCompress.h>
|
||||||
#include "gui/dialogs/OneSixModEditDialog.h"
|
#include "gui/dialogs/OneSixModEditDialog.h"
|
||||||
#include "logger/QsLog.h"
|
#include "logger/QsLog.h"
|
||||||
#include "logic/assets/AssetsIndex.h"
|
|
||||||
#include "logic/assets/AssetsUtils.h"
|
#include "logic/assets/AssetsUtils.h"
|
||||||
|
|
||||||
OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_obj,
|
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();
|
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);
|
QString target_path = PathCombine(virtualRoot.path(), map);
|
||||||
QFile target(target_path);
|
QFile target(target_path);
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "OneSixLibrary.h"
|
#include "OneSixLibrary.h"
|
||||||
#include "OneSixInstance.h"
|
#include "OneSixInstance.h"
|
||||||
#include "net/ForgeMirrors.h"
|
#include "net/ForgeMirrors.h"
|
||||||
|
#include "assets/AssetsUtils.h"
|
||||||
|
|
||||||
#include "pathutils.h"
|
#include "pathutils.h"
|
||||||
#include <JlCompress.h>
|
#include <JlCompress.h>
|
||||||
@ -50,7 +51,7 @@ void OneSixUpdate::executeTask()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_only_prepare)
|
if (m_only_prepare)
|
||||||
{
|
{
|
||||||
if (m_inst->shouldUpdate())
|
if (m_inst->shouldUpdate())
|
||||||
{
|
{
|
||||||
@ -93,7 +94,7 @@ void OneSixUpdate::checkJavaOnline()
|
|||||||
|
|
||||||
checker.reset(new JavaChecker());
|
checker.reset(new JavaChecker());
|
||||||
connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this,
|
connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this,
|
||||||
SLOT(checkFinishedOnline(JavaCheckResult)));
|
SLOT(checkFinishedOnline(JavaCheckResult)));
|
||||||
checker->performCheck(java_path);
|
checker->performCheck(java_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,6 +194,96 @@ void OneSixUpdate::versionFileFailed()
|
|||||||
emitFailed("Failed to download the version description. Try again.");
|
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()
|
void OneSixUpdate::jarlibStart()
|
||||||
{
|
{
|
||||||
setStatus("Getting the library files from Mojang.");
|
setStatus("Getting the library files from Mojang.");
|
||||||
@ -215,7 +306,7 @@ void OneSixUpdate::jarlibStart()
|
|||||||
targetstr += version->id + "/" + version->id + ".jar";
|
targetstr += version->id + "/" + version->id + ".jar";
|
||||||
|
|
||||||
auto job = new NetJob("Libraries for instance " + inst->name());
|
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);
|
jarlibDownloadJob.reset(job);
|
||||||
|
|
||||||
auto libs = version->getActiveNativeLibs();
|
auto libs = version->getActiveNativeLibs();
|
||||||
@ -265,7 +356,7 @@ void OneSixUpdate::jarlibStart()
|
|||||||
|
|
||||||
void OneSixUpdate::jarlibFinished()
|
void OneSixUpdate::jarlibFinished()
|
||||||
{
|
{
|
||||||
prepareForLaunch();
|
assetIndexStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OneSixUpdate::jarlibFailed()
|
void OneSixUpdate::jarlibFailed()
|
||||||
|
@ -43,6 +43,13 @@ slots:
|
|||||||
void jarlibFinished();
|
void jarlibFinished();
|
||||||
void jarlibFailed();
|
void jarlibFailed();
|
||||||
|
|
||||||
|
void assetIndexStart();
|
||||||
|
void assetIndexFinished();
|
||||||
|
void assetIndexFailed();
|
||||||
|
|
||||||
|
void assetsFinished();
|
||||||
|
void assetsFailed();
|
||||||
|
|
||||||
void checkJavaOnline();
|
void checkJavaOnline();
|
||||||
void checkFinishedOnline(JavaCheckResult result);
|
void checkFinishedOnline(JavaCheckResult result);
|
||||||
void checkFinishedOffline(JavaCheckResult result);
|
void checkFinishedOffline(JavaCheckResult result);
|
||||||
|
@ -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.
|
|
||||||
*/
|
|
@ -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
|
|
@ -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()
|
|
||||||
{
|
|
||||||
}
|
|
@ -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;
|
|
||||||
};
|
|
@ -28,54 +28,64 @@ namespace AssetsUtils
|
|||||||
void migrateOldAssets()
|
void migrateOldAssets()
|
||||||
{
|
{
|
||||||
QDir assets_dir("assets");
|
QDir assets_dir("assets");
|
||||||
if(!assets_dir.exists()) return;
|
if (!assets_dir.exists())
|
||||||
|
return;
|
||||||
assets_dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
|
assets_dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
|
||||||
int base_length = assets_dir.path().length();
|
int base_length = assets_dir.path().length();
|
||||||
|
|
||||||
QList<QString> blacklist = {"indexes", "objects", "virtual"};
|
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");
|
QDir objects_dir("assets/objects");
|
||||||
|
|
||||||
QDirIterator iterator(assets_dir, QDirIterator::Subdirectories);
|
QDirIterator iterator(assets_dir, QDirIterator::Subdirectories);
|
||||||
int successes = 0;
|
int successes = 0;
|
||||||
int failures = 0;
|
int failures = 0;
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext())
|
||||||
|
{
|
||||||
QString currentDir = iterator.next();
|
QString currentDir = iterator.next();
|
||||||
currentDir = currentDir.remove(0, base_length+1);
|
currentDir = currentDir.remove(0, base_length + 1);
|
||||||
|
|
||||||
bool ignore = false;
|
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();
|
QString filename = iterator.filePath();
|
||||||
|
|
||||||
QFile input(filename);
|
QFile input(filename);
|
||||||
input.open(QIODevice::ReadOnly | QIODevice::WriteOnly);
|
input.open(QIODevice::ReadOnly | QIODevice::WriteOnly);
|
||||||
QString sha1sum = QCryptographicHash::hash(input.readAll(), QCryptographicHash::Sha1)
|
QString sha1sum =
|
||||||
.toHex()
|
QCryptographicHash::hash(input.readAll(), QCryptographicHash::Sha1)
|
||||||
.constData();
|
.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();
|
QLOG_DEBUG() << "Processing" << object_name << ":" << sha1sum << input.size();
|
||||||
|
|
||||||
QString object_tlk = sha1sum.left(2);
|
QString object_tlk = sha1sum.left(2);
|
||||||
QString object_tlk_dir = objects_dir.path() + "/" + object_tlk;
|
QString object_tlk_dir = objects_dir.path() + "/" + object_tlk;
|
||||||
|
|
||||||
QDir tlk_dir(object_tlk_dir);
|
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;
|
QString new_filename = tlk_dir.path() + "/" + sha1sum;
|
||||||
QFile new_object(new_filename);
|
QFile new_object(new_filename);
|
||||||
if(!new_object.exists())
|
if (!new_object.exists())
|
||||||
{
|
{
|
||||||
bool rename_success = input.rename(new_filename);
|
bool rename_success = input.rename(new_filename);
|
||||||
QLOG_DEBUG() << " Doesn't exist, copying to" << new_filename << ":" << QString::number(rename_success);
|
QLOG_DEBUG() << " Doesn't exist, copying to" << new_filename << ":"
|
||||||
if(rename_success) successes++;
|
<< QString::number(rename_success);
|
||||||
else failures++;
|
if (rename_success)
|
||||||
|
successes++;
|
||||||
|
else
|
||||||
|
failures++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -85,26 +95,31 @@ void migrateOldAssets()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(successes + failures == 0) {
|
if (successes + failures == 0)
|
||||||
|
{
|
||||||
QLOG_DEBUG() << "No legacy assets needed importing.";
|
QLOG_DEBUG() << "No legacy assets needed importing.";
|
||||||
}
|
}
|
||||||
else
|
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);
|
QDirIterator cleanup_iterator(assets_dir);
|
||||||
|
|
||||||
while (cleanup_iterator.hasNext()) {
|
while (cleanup_iterator.hasNext())
|
||||||
|
{
|
||||||
QString currentDir = cleanup_iterator.next();
|
QString currentDir = cleanup_iterator.next();
|
||||||
currentDir = currentDir.remove(0, base_length+1);
|
currentDir = currentDir.remove(0, base_length + 1);
|
||||||
|
|
||||||
bool ignore = false;
|
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();
|
QString path = cleanup_iterator.filePath();
|
||||||
QDir folder(path);
|
QDir folder(path);
|
||||||
|
|
||||||
@ -122,18 +137,18 @@ void migrateOldAssets()
|
|||||||
*/
|
*/
|
||||||
bool loadAssetsIndexJson(QString path, AssetsIndex *index)
|
bool loadAssetsIndexJson(QString path, AssetsIndex *index)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
"objects": {
|
"objects": {
|
||||||
"icons/icon_16x16.png": {
|
"icons/icon_16x16.png": {
|
||||||
"hash": "bdf48ef6b5d0d23bbb02e17d04865216179f510a",
|
"hash": "bdf48ef6b5d0d23bbb02e17d04865216179f510a",
|
||||||
"size": 3665
|
"size": 3665
|
||||||
},
|
},
|
||||||
...
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
*/
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
|
|
||||||
@ -155,7 +170,8 @@ bool loadAssetsIndexJson(QString path, AssetsIndex *index)
|
|||||||
// Fail if the JSON is invalid.
|
// Fail if the JSON is invalid.
|
||||||
if (parseError.error != QJsonParseError::NoError)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +185,7 @@ bool loadAssetsIndexJson(QString path, AssetsIndex *index)
|
|||||||
QJsonObject root = jsonDoc.object();
|
QJsonObject root = jsonDoc.object();
|
||||||
|
|
||||||
QJsonValue isVirtual = root.value("virtual");
|
QJsonValue isVirtual = root.value("virtual");
|
||||||
if(!isVirtual.isUndefined())
|
if (!isVirtual.isUndefined())
|
||||||
{
|
{
|
||||||
index->isVirtual = isVirtual.toBool(false);
|
index->isVirtual = isVirtual.toBool(false);
|
||||||
}
|
}
|
||||||
@ -177,48 +193,35 @@ bool loadAssetsIndexJson(QString path, AssetsIndex *index)
|
|||||||
QJsonValue objects = root.value("objects");
|
QJsonValue objects = root.value("objects");
|
||||||
QVariantMap map = objects.toVariant().toMap();
|
QVariantMap map = objects.toVariant().toMap();
|
||||||
|
|
||||||
for(QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter) {
|
for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
|
||||||
//QLOG_DEBUG() << iter.key();
|
{
|
||||||
|
// QLOG_DEBUG() << iter.key();
|
||||||
|
|
||||||
QVariant variant = iter.value();
|
QVariant variant = iter.value();
|
||||||
QVariantMap nested_objects = variant.toMap();
|
QVariantMap nested_objects = variant.toMap();
|
||||||
|
|
||||||
AssetObject object;
|
AssetObject object;
|
||||||
|
|
||||||
for(QVariantMap::const_iterator nested_iter = nested_objects.begin(); nested_iter != nested_objects.end(); ++nested_iter) {
|
for (QVariantMap::const_iterator nested_iter = nested_objects.begin();
|
||||||
//QLOG_DEBUG() << nested_iter.key() << nested_iter.value().toString();
|
nested_iter != nested_objects.end(); ++nested_iter)
|
||||||
|
{
|
||||||
|
// QLOG_DEBUG() << nested_iter.key() << nested_iter.value().toString();
|
||||||
QString key = nested_iter.key();
|
QString key = nested_iter.key();
|
||||||
QVariant value = nested_iter.value();
|
QVariant value = nested_iter.value();
|
||||||
|
|
||||||
if(key == "hash")
|
if (key == "hash")
|
||||||
{
|
{
|
||||||
object.hash = value.toString();
|
object.hash = value.toString();
|
||||||
}
|
}
|
||||||
else if(key == "size")
|
else if (key == "size")
|
||||||
{
|
{
|
||||||
object.size = value.toDouble();
|
object.size = value.toDouble();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
index->objects->insert(iter.key(), object);
|
index->objects.insert(iter.key(), object);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,22 @@
|
|||||||
|
|
||||||
#pragma once
|
#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
|
namespace AssetsUtils
|
||||||
{
|
{
|
||||||
|
@ -14,12 +14,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MultiMC.h"
|
#include "MultiMC.h"
|
||||||
#include "FileDownload.h"
|
#include "MD5EtagDownload.h"
|
||||||
#include <pathutils.h>
|
#include <pathutils.h>
|
||||||
#include <QCryptographicHash>
|
#include <QCryptographicHash>
|
||||||
#include "logger/QsLog.h"
|
#include "logger/QsLog.h"
|
||||||
|
|
||||||
FileDownload::FileDownload(QUrl url, QString target_path) : NetAction()
|
MD5EtagDownload::MD5EtagDownload(QUrl url, QString target_path) : NetAction()
|
||||||
{
|
{
|
||||||
m_url = url;
|
m_url = url;
|
||||||
m_target_path = target_path;
|
m_target_path = target_path;
|
||||||
@ -27,7 +27,7 @@ FileDownload::FileDownload(QUrl url, QString target_path) : NetAction()
|
|||||||
m_status = Job_NotStarted;
|
m_status = Job_NotStarted;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDownload::start()
|
void MD5EtagDownload::start()
|
||||||
{
|
{
|
||||||
QString filename = m_target_path;
|
QString filename = m_target_path;
|
||||||
m_output_file.setFileName(filename);
|
m_output_file.setFileName(filename);
|
||||||
@ -58,7 +58,7 @@ void FileDownload::start()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QLOG_INFO() << "Downloading " << m_url.toString();
|
QLOG_INFO() << "Downloading " << m_url.toString() << " expecting " << m_expected_md5;
|
||||||
QNetworkRequest request(m_url);
|
QNetworkRequest request(m_url);
|
||||||
request.setRawHeader(QString("If-None-Match").toLatin1(), m_expected_md5.toLatin1());
|
request.setRawHeader(QString("If-None-Match").toLatin1(), m_expected_md5.toLatin1());
|
||||||
request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
|
request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
|
||||||
@ -75,19 +75,19 @@ void FileDownload::start()
|
|||||||
connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead()));
|
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);
|
emit progress(index_within_job, bytesReceived, bytesTotal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDownload::downloadError(QNetworkReply::NetworkError error)
|
void MD5EtagDownload::downloadError(QNetworkReply::NetworkError error)
|
||||||
{
|
{
|
||||||
// error happened during download.
|
// error happened during download.
|
||||||
// TODO: log the reason why
|
// TODO: log the reason why
|
||||||
m_status = Job_Failed;
|
m_status = Job_Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDownload::downloadFinished()
|
void MD5EtagDownload::downloadFinished()
|
||||||
{
|
{
|
||||||
// if the download succeeded
|
// if the download succeeded
|
||||||
if (m_status != Job_Failed)
|
if (m_status != Job_Failed)
|
||||||
@ -96,6 +96,7 @@ void FileDownload::downloadFinished()
|
|||||||
m_status = Job_Finished;
|
m_status = Job_Finished;
|
||||||
m_output_file.close();
|
m_output_file.close();
|
||||||
|
|
||||||
|
QLOG_INFO() << "Finished " << m_url.toString() << " got " << m_reply->rawHeader("ETag").constData();
|
||||||
m_reply.reset();
|
m_reply.reset();
|
||||||
emit succeeded(index_within_job);
|
emit succeeded(index_within_job);
|
||||||
return;
|
return;
|
||||||
@ -110,7 +111,7 @@ void FileDownload::downloadFinished()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDownload::downloadReadyRead()
|
void MD5EtagDownload::downloadReadyRead()
|
||||||
{
|
{
|
||||||
if (!m_output_file.isOpen())
|
if (!m_output_file.isOpen())
|
||||||
{
|
{
|
@ -18,8 +18,8 @@
|
|||||||
#include "NetAction.h"
|
#include "NetAction.h"
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
typedef std::shared_ptr<class FileDownload> FileDownloadPtr;
|
typedef std::shared_ptr<class MD5EtagDownload> Md5EtagDownloadPtr;
|
||||||
class FileDownload : public NetAction
|
class MD5EtagDownload : public NetAction
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -35,10 +35,10 @@ public:
|
|||||||
QFile m_output_file;
|
QFile m_output_file;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FileDownload(QUrl url, QString target_path);
|
explicit MD5EtagDownload(QUrl url, QString target_path);
|
||||||
static FileDownloadPtr make(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
|
protected
|
||||||
slots:
|
slots:
|
@ -16,7 +16,7 @@
|
|||||||
#include "NetJob.h"
|
#include "NetJob.h"
|
||||||
#include "pathutils.h"
|
#include "pathutils.h"
|
||||||
#include "MultiMC.h"
|
#include "MultiMC.h"
|
||||||
#include "FileDownload.h"
|
#include "MD5EtagDownload.h"
|
||||||
#include "ByteArrayDownload.h"
|
#include "ByteArrayDownload.h"
|
||||||
#include "CacheDownload.h"
|
#include "CacheDownload.h"
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include "NetAction.h"
|
#include "NetAction.h"
|
||||||
#include "ByteArrayDownload.h"
|
#include "ByteArrayDownload.h"
|
||||||
#include "FileDownload.h"
|
#include "MD5EtagDownload.h"
|
||||||
#include "CacheDownload.h"
|
#include "CacheDownload.h"
|
||||||
#include "HttpMetaCache.h"
|
#include "HttpMetaCache.h"
|
||||||
#include "ForgeXzDownload.h"
|
#include "ForgeXzDownload.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user