summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2016-10-28 02:19:19 +0200
committerPetr Mrázek <peterix@gmail.com>2016-10-28 02:19:19 +0200
commitdd0e996081ae820a0f16b5a6854a8a6274c5edf5 (patch)
tree9d9f0ba7ff51b546d15106f71841f9de42a09f2b
parent3d94fb8d24c6012d5d1cdee61c99e62847c06ad9 (diff)
downloadMultiMC-dd0e996081ae820a0f16b5a6854a8a6274c5edf5.tar
MultiMC-dd0e996081ae820a0f16b5a6854a8a6274c5edf5.tar.gz
MultiMC-dd0e996081ae820a0f16b5a6854a8a6274c5edf5.tar.lz
MultiMC-dd0e996081ae820a0f16b5a6854a8a6274c5edf5.tar.xz
MultiMC-dd0e996081ae820a0f16b5a6854a8a6274c5edf5.zip
GH-1697 always stale files tolerate errors if a local copy is present
This fixes the situation when liteloader snapshot site is broken and there's an older local snapshot already present.
-rw-r--r--api/logic/minecraft/Library.cpp9
-rw-r--r--api/logic/net/ByteArraySink.h5
-rw-r--r--api/logic/net/Download.cpp27
-rw-r--r--api/logic/net/Download.h17
-rw-r--r--api/logic/net/FileSink.cpp5
-rw-r--r--api/logic/net/FileSink.h1
-rw-r--r--api/logic/net/MetaCacheSink.cpp6
-rw-r--r--api/logic/net/MetaCacheSink.h1
-rw-r--r--api/logic/net/NetAction.h3
-rw-r--r--api/logic/net/Sink.h1
10 files changed, 64 insertions, 11 deletions
diff --git a/api/logic/minecraft/Library.cpp b/api/logic/minecraft/Library.cpp
index 8bbd5503..5a75fe79 100644
--- a/api/logic/minecraft/Library.cpp
+++ b/api/logic/minecraft/Library.cpp
@@ -131,6 +131,11 @@ QList< std::shared_ptr< NetAction > > Library::getDownloads(OpSys system, class
}
return true;
}
+ Net::Download::Options options;
+ if(isAlwaysStale)
+ {
+ options |= Net::Download::Option::AcceptLocalFiles;
+ }
if (isForge)
{
out.append(ForgeXzDownload::make(storage, entry));
@@ -140,13 +145,13 @@ QList< std::shared_ptr< NetAction > > Library::getDownloads(OpSys system, class
if(sha1.size())
{
auto rawSha1 = QByteArray::fromHex(sha1.toLatin1());
- auto dl = Net::Download::makeCached(url, entry);
+ auto dl = Net::Download::makeCached(url, entry, options);
dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1));
out.append(dl);
}
else
- out.append(Net::Download::makeCached(url, entry));
+ out.append(Net::Download::makeCached(url, entry, options));
}
return true;
};
diff --git a/api/logic/net/ByteArraySink.h b/api/logic/net/ByteArraySink.h
index 3deef1ed..03b77fcc 100644
--- a/api/logic/net/ByteArraySink.h
+++ b/api/logic/net/ByteArraySink.h
@@ -51,6 +51,11 @@ public:
return Job_Failed;
}
+ bool hasLocalData() override
+ {
+ return false;
+ }
+
private:
QByteArray * m_output;
};
diff --git a/api/logic/net/Download.cpp b/api/logic/net/Download.cpp
index 7610cae3..3d53ded0 100644
--- a/api/logic/net/Download.cpp
+++ b/api/logic/net/Download.cpp
@@ -31,10 +31,11 @@ Download::Download():NetAction()
m_status = Job_NotStarted;
}
-Download::Ptr Download::makeCached(QUrl url, MetaEntryPtr entry)
+Download::Ptr Download::makeCached(QUrl url, MetaEntryPtr entry, Options options)
{
Download * dl = new Download();
dl->m_url = url;
+ dl->m_options = options;
auto md5Node = new ChecksumValidator(QCryptographicHash::Md5);
auto cachedNode = new MetaCacheSink(entry, md5Node);
dl->m_sink.reset(cachedNode);
@@ -42,18 +43,20 @@ Download::Ptr Download::makeCached(QUrl url, MetaEntryPtr entry)
return std::shared_ptr<Download>(dl);
}
-Download::Ptr Download::makeByteArray(QUrl url, QByteArray *output)
+Download::Ptr Download::makeByteArray(QUrl url, QByteArray *output, Options options)
{
Download * dl = new Download();
dl->m_url = url;
+ dl->m_options = options;
dl->m_sink.reset(new ByteArraySink(output));
return std::shared_ptr<Download>(dl);
}
-Download::Ptr Download::makeFile(QUrl url, QString path)
+Download::Ptr Download::makeFile(QUrl url, QString path, Options options)
{
Download * dl = new Download();
dl->m_url = url;
+ dl->m_options = options;
dl->m_sink.reset(new FileSink(path));
return std::shared_ptr<Download>(dl);
}
@@ -118,6 +121,14 @@ void Download::downloadError(QNetworkReply::NetworkError error)
}
else
{
+ if(m_options & Option::AcceptLocalFiles)
+ {
+ if(m_sink->hasLocalData())
+ {
+ m_status = Job_Failed_Proceed;
+ return;
+ }
+ }
// error happened during download.
qCritical() << "Failed " << m_url.toString() << " with reason " << error;
m_status = Job_Failed;
@@ -162,7 +173,15 @@ void Download::downloadFinished()
}
// if the download failed before this point ...
- if (m_status == Job_Failed)
+ if (m_status == Job_Failed_Proceed)
+ {
+ qDebug() << "Download failed but we are allowed to proceed:" << m_url.toString();
+ m_sink->abort();
+ m_reply.reset();
+ emit succeeded(m_index_within_job);
+ return;
+ }
+ else if (m_status == Job_Failed)
{
qDebug() << "Download failed in previous step:" << m_url.toString();
m_sink->abort();
diff --git a/api/logic/net/Download.h b/api/logic/net/Download.h
index fab39ffe..d417f660 100644
--- a/api/logic/net/Download.h
+++ b/api/logic/net/Download.h
@@ -28,14 +28,20 @@ class MULTIMC_LOGIC_EXPORT Download : public NetAction
public: /* types */
typedef std::shared_ptr<class Download> Ptr;
+ enum class Option
+ {
+ NoOptions = 0,
+ AcceptLocalFiles = 1
+ };
+ Q_DECLARE_FLAGS(Options, Option)
protected: /* con/des */
explicit Download();
public:
virtual ~Download(){};
- static Download::Ptr makeCached(QUrl url, MetaEntryPtr entry);
- static Download::Ptr makeByteArray(QUrl url, QByteArray *output);
- static Download::Ptr makeFile(QUrl url, QString path);
+ static Download::Ptr makeCached(QUrl url, MetaEntryPtr entry, Options options = Option::NoOptions);
+ static Download::Ptr makeByteArray(QUrl url, QByteArray *output, Options options = Option::NoOptions);
+ static Download::Ptr makeFile(QUrl url, QString path, Options options = Option::NoOptions);
public: /* methods */
QString getTargetFilepath()
@@ -62,5 +68,8 @@ private: /* data */
// FIXME: remove this, it has no business being here.
QString m_target_path;
std::unique_ptr<Sink> m_sink;
+ Options m_options;
};
-} \ No newline at end of file
+}
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(Net::Download::Options)
diff --git a/api/logic/net/FileSink.cpp b/api/logic/net/FileSink.cpp
index e912b1c9..7dfc4336 100644
--- a/api/logic/net/FileSink.cpp
+++ b/api/logic/net/FileSink.cpp
@@ -97,4 +97,9 @@ JobStatus FileSink::finalizeCache(QNetworkReply &)
return Job_Finished;
}
+bool FileSink::hasLocalData()
+{
+ QFileInfo info(m_filename);
+ return info.exists() && info.size() != 0;
+}
}
diff --git a/api/logic/net/FileSink.h b/api/logic/net/FileSink.h
index 7adc9c47..035d5bfd 100644
--- a/api/logic/net/FileSink.h
+++ b/api/logic/net/FileSink.h
@@ -14,6 +14,7 @@ public: /* methods */
JobStatus write(QByteArray & data) override;
JobStatus abort() override;
JobStatus finalize(QNetworkReply & reply) override;
+ bool hasLocalData() override;
protected: /* methods */
virtual JobStatus initCache(QNetworkRequest &);
diff --git a/api/logic/net/MetaCacheSink.cpp b/api/logic/net/MetaCacheSink.cpp
index 539b4bb3..c9d75310 100644
--- a/api/logic/net/MetaCacheSink.cpp
+++ b/api/logic/net/MetaCacheSink.cpp
@@ -56,4 +56,10 @@ JobStatus MetaCacheSink::finalizeCache(QNetworkReply & reply)
ENV.metacache()->updateEntry(m_entry);
return Job_Finished;
}
+
+bool MetaCacheSink::hasLocalData()
+{
+ QFileInfo info(m_filename);
+ return info.exists() && info.size() != 0;
+}
}
diff --git a/api/logic/net/MetaCacheSink.h b/api/logic/net/MetaCacheSink.h
index 98e9bba1..0f3bbdf6 100644
--- a/api/logic/net/MetaCacheSink.h
+++ b/api/logic/net/MetaCacheSink.h
@@ -9,6 +9,7 @@ class MetaCacheSink : public FileSink
public: /* con/des */
MetaCacheSink(MetaEntryPtr entry, ChecksumValidator * md5sum);
virtual ~MetaCacheSink();
+ bool hasLocalData() override;
protected: /* methods */
JobStatus initCache(QNetworkRequest & request) override;
diff --git a/api/logic/net/NetAction.h b/api/logic/net/NetAction.h
index 07456ce1..aee68230 100644
--- a/api/logic/net/NetAction.h
+++ b/api/logic/net/NetAction.h
@@ -29,7 +29,8 @@ enum JobStatus
Job_InProgress,
Job_Finished,
Job_Failed,
- Job_Aborted
+ Job_Aborted,
+ Job_Failed_Proceed
};
typedef std::shared_ptr<class NetAction> NetActionPtr;
diff --git a/api/logic/net/Sink.h b/api/logic/net/Sink.h
index 53f2b221..de9b1722 100644
--- a/api/logic/net/Sink.h
+++ b/api/logic/net/Sink.h
@@ -17,6 +17,7 @@ public: /* methods */
virtual JobStatus write(QByteArray & data) = 0;
virtual JobStatus abort() = 0;
virtual JobStatus finalize(QNetworkReply & reply) = 0;
+ virtual bool hasLocalData() = 0;
void addValidator(Validator * validator)
{