Reformat and (slightly) decruft all the things.
This commit is contained in:
@ -1,6 +1,21 @@
|
||||
/* 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 "ByteArrayDownload.h"
|
||||
#include "MultiMC.h"
|
||||
#include <logger/QsLog.h>
|
||||
#include "logger/QsLog.h"
|
||||
|
||||
ByteArrayDownload::ByteArrayDownload(QUrl url) : NetAction()
|
||||
{
|
||||
|
@ -1,3 +1,18 @@
|
||||
/* 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 "NetAction.h"
|
||||
|
||||
|
@ -1,3 +1,18 @@
|
||||
/* 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 "MultiMC.h"
|
||||
#include "CacheDownload.h"
|
||||
#include <pathutils.h>
|
||||
@ -5,7 +20,7 @@
|
||||
#include <QCryptographicHash>
|
||||
#include <QFileInfo>
|
||||
#include <QDateTime>
|
||||
#include <logger/QsLog.h>
|
||||
#include "logger/QsLog.h"
|
||||
|
||||
CacheDownload::CacheDownload(QUrl url, MetaEntryPtr entry)
|
||||
: NetAction(), md5sum(QCryptographicHash::Md5)
|
||||
@ -33,12 +48,13 @@ void CacheDownload::start()
|
||||
}
|
||||
QLOG_INFO() << "Downloading " << m_url.toString();
|
||||
QNetworkRequest request(m_url);
|
||||
if(m_entry->remote_changed_timestamp.size())
|
||||
request.setRawHeader(QString("If-Modified-Since").toLatin1(), m_entry->remote_changed_timestamp.toLatin1());
|
||||
if(m_entry->etag.size())
|
||||
if (m_entry->remote_changed_timestamp.size())
|
||||
request.setRawHeader(QString("If-Modified-Since").toLatin1(),
|
||||
m_entry->remote_changed_timestamp.toLatin1());
|
||||
if (m_entry->etag.size())
|
||||
request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->etag.toLatin1());
|
||||
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader,"MultiMC/5.0 (Cached)");
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
|
||||
|
||||
auto worker = MMC->qnam();
|
||||
QNetworkReply *rep = worker->get(request);
|
||||
@ -91,7 +107,7 @@ void CacheDownload::downloadFinished()
|
||||
QFileInfo output_file_info(m_target_path);
|
||||
|
||||
m_entry->etag = m_reply->rawHeader("ETag").constData();
|
||||
if(m_reply->hasRawHeader("Last-Modified"))
|
||||
if (m_reply->hasRawHeader("Last-Modified"))
|
||||
{
|
||||
m_entry->remote_changed_timestamp = m_reply->rawHeader("Last-Modified").constData();
|
||||
}
|
||||
|
@ -1,3 +1,18 @@
|
||||
/* 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 "NetAction.h"
|
||||
|
@ -1,12 +1,25 @@
|
||||
/* 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 "MultiMC.h"
|
||||
#include "FileDownload.h"
|
||||
#include <pathutils.h>
|
||||
#include <QCryptographicHash>
|
||||
#include <logger/QsLog.h>
|
||||
#include "logger/QsLog.h"
|
||||
|
||||
|
||||
FileDownload::FileDownload ( QUrl url, QString target_path )
|
||||
:NetAction()
|
||||
FileDownload::FileDownload(QUrl url, QString target_path) : NetAction()
|
||||
{
|
||||
m_url = url;
|
||||
m_target_path = target_path;
|
||||
@ -18,15 +31,18 @@ FileDownload::FileDownload ( QUrl url, QString target_path )
|
||||
void FileDownload::start()
|
||||
{
|
||||
QString filename = m_target_path;
|
||||
m_output_file.setFileName ( filename );
|
||||
m_output_file.setFileName(filename);
|
||||
// if there already is a file and md5 checking is in effect and it can be opened
|
||||
if ( m_output_file.exists() && m_output_file.open ( QIODevice::ReadOnly ) )
|
||||
if (m_output_file.exists() && m_output_file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
// check the md5 against the expected one
|
||||
QString hash = QCryptographicHash::hash ( m_output_file.readAll(), QCryptographicHash::Md5 ).toHex().constData();
|
||||
QString hash =
|
||||
QCryptographicHash::hash(m_output_file.readAll(), QCryptographicHash::Md5)
|
||||
.toHex()
|
||||
.constData();
|
||||
m_output_file.close();
|
||||
// skip this file if they match
|
||||
if ( m_check_md5 && hash == m_expected_md5 )
|
||||
if (m_check_md5 && hash == m_expected_md5)
|
||||
{
|
||||
QLOG_INFO() << "Skipping " << m_url.toString() << ": md5 match.";
|
||||
emit succeeded(index_within_job);
|
||||
@ -37,33 +53,35 @@ void FileDownload::start()
|
||||
m_expected_md5 = hash;
|
||||
}
|
||||
}
|
||||
if(!ensureFilePathExists(filename))
|
||||
if (!ensureFilePathExists(filename))
|
||||
{
|
||||
emit failed(index_within_job);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
QLOG_INFO() << "Downloading " << m_url.toString();
|
||||
QNetworkRequest request ( m_url );
|
||||
request.setRawHeader(QString("If-None-Match").toLatin1(), m_expected_md5.toLatin1());
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader,"MultiMC/5.0 (Uncached)");
|
||||
|
||||
QNetworkRequest request(m_url);
|
||||
request.setRawHeader(QString("If-None-Match").toLatin1(), m_expected_md5.toLatin1());
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
|
||||
|
||||
auto worker = MMC->qnam();
|
||||
QNetworkReply * rep = worker->get ( request );
|
||||
|
||||
m_reply = std::shared_ptr<QNetworkReply> ( rep );
|
||||
connect ( rep, SIGNAL ( downloadProgress ( qint64,qint64 ) ), SLOT ( downloadProgress ( qint64,qint64 ) ) );
|
||||
connect ( rep, SIGNAL ( finished() ), SLOT ( downloadFinished() ) );
|
||||
connect ( rep, SIGNAL ( error ( QNetworkReply::NetworkError ) ), SLOT ( downloadError ( QNetworkReply::NetworkError ) ) );
|
||||
connect ( rep, SIGNAL ( readyRead() ), SLOT ( downloadReadyRead() ) );
|
||||
QNetworkReply *rep = worker->get(request);
|
||||
|
||||
m_reply = std::shared_ptr<QNetworkReply>(rep);
|
||||
connect(rep, SIGNAL(downloadProgress(qint64, qint64)),
|
||||
SLOT(downloadProgress(qint64, qint64)));
|
||||
connect(rep, SIGNAL(finished()), SLOT(downloadFinished()));
|
||||
connect(rep, SIGNAL(error(QNetworkReply::NetworkError)),
|
||||
SLOT(downloadError(QNetworkReply::NetworkError)));
|
||||
connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead()));
|
||||
}
|
||||
|
||||
void FileDownload::downloadProgress ( qint64 bytesReceived, qint64 bytesTotal )
|
||||
void FileDownload::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 FileDownload::downloadError(QNetworkReply::NetworkError error)
|
||||
{
|
||||
// error happened during download.
|
||||
// TODO: log the reason why
|
||||
@ -73,7 +91,7 @@ void FileDownload::downloadError ( QNetworkReply::NetworkError error )
|
||||
void FileDownload::downloadFinished()
|
||||
{
|
||||
// if the download succeeded
|
||||
if ( m_status != Job_Failed )
|
||||
if (m_status != Job_Failed)
|
||||
{
|
||||
// nothing went wrong...
|
||||
m_status = Job_Finished;
|
||||
@ -95,9 +113,9 @@ void FileDownload::downloadFinished()
|
||||
|
||||
void FileDownload::downloadReadyRead()
|
||||
{
|
||||
if(!m_opened_for_saving)
|
||||
if (!m_opened_for_saving)
|
||||
{
|
||||
if ( !m_output_file.open ( QIODevice::WriteOnly ) )
|
||||
if (!m_output_file.open(QIODevice::WriteOnly))
|
||||
{
|
||||
/*
|
||||
* Can't open the file... the job failed
|
||||
@ -108,5 +126,5 @@ void FileDownload::downloadReadyRead()
|
||||
}
|
||||
m_opened_for_saving = true;
|
||||
}
|
||||
m_output_file.write ( m_reply->readAll() );
|
||||
m_output_file.write(m_reply->readAll());
|
||||
}
|
||||
|
@ -1,3 +1,18 @@
|
||||
/* 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 "NetAction.h"
|
||||
|
@ -1,3 +1,18 @@
|
||||
/* 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 "MultiMC.h"
|
||||
#include "ForgeXzDownload.h"
|
||||
#include <pathutils.h>
|
||||
@ -5,10 +20,9 @@
|
||||
#include <QCryptographicHash>
|
||||
#include <QFileInfo>
|
||||
#include <QDateTime>
|
||||
#include <logger/QsLog.h>
|
||||
#include "logger/QsLog.h"
|
||||
|
||||
ForgeXzDownload::ForgeXzDownload(QUrl url, MetaEntryPtr entry)
|
||||
: NetAction()
|
||||
ForgeXzDownload::ForgeXzDownload(QUrl url, MetaEntryPtr entry) : NetAction()
|
||||
{
|
||||
QString urlstr = url.toString();
|
||||
urlstr.append(".pack.xz");
|
||||
@ -35,7 +49,7 @@ void ForgeXzDownload::start()
|
||||
QLOG_INFO() << "Downloading " << m_url.toString();
|
||||
QNetworkRequest request(m_url);
|
||||
request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->etag.toLatin1());
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader,"MultiMC/5.0 (Cached)");
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
|
||||
|
||||
auto worker = MMC->qnam();
|
||||
QNetworkReply *rep = worker->get(request);
|
||||
@ -96,7 +110,7 @@ void ForgeXzDownload::downloadFinished()
|
||||
|
||||
void ForgeXzDownload::downloadReadyRead()
|
||||
{
|
||||
|
||||
|
||||
if (!m_opened_for_saving)
|
||||
{
|
||||
if (!m_pack200_xz_file.open())
|
||||
@ -154,7 +168,7 @@ void ForgeXzDownload::decompressAndInstall()
|
||||
{
|
||||
if (b.in_pos == b.in_size)
|
||||
{
|
||||
b.in_size = m_pack200_xz_file.read((char*)in, sizeof(in));
|
||||
b.in_size = m_pack200_xz_file.read((char *)in, sizeof(in));
|
||||
b.in_pos = 0;
|
||||
}
|
||||
|
||||
@ -162,7 +176,7 @@ void ForgeXzDownload::decompressAndInstall()
|
||||
|
||||
if (b.out_pos == sizeof(out))
|
||||
{
|
||||
if (pack200_file.write((char*)out, b.out_pos) != b.out_pos)
|
||||
if (pack200_file.write((char *)out, b.out_pos) != b.out_pos)
|
||||
{
|
||||
// msg = "Write error\n";
|
||||
xz_dec_end(s);
|
||||
@ -182,7 +196,7 @@ void ForgeXzDownload::decompressAndInstall()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pack200_file.write((char*)out, b.out_pos) != b.out_pos )
|
||||
if (pack200_file.write((char *)out, b.out_pos) != b.out_pos)
|
||||
{
|
||||
// write error
|
||||
pack200_file.close();
|
||||
@ -236,7 +250,7 @@ void ForgeXzDownload::decompressAndInstall()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// revert pack200
|
||||
pack200_file.close();
|
||||
QString pack_name = pack200_file.fileName();
|
||||
@ -244,16 +258,16 @@ void ForgeXzDownload::decompressAndInstall()
|
||||
{
|
||||
unpack_200(pack_name.toStdString(), m_target_path.toStdString());
|
||||
}
|
||||
catch(std::runtime_error & err)
|
||||
catch (std::runtime_error &err)
|
||||
{
|
||||
QLOG_ERROR() << "Error unpacking " << pack_name.toUtf8() << " : " << err.what();
|
||||
QFile f(m_target_path);
|
||||
if(f.exists())
|
||||
if (f.exists())
|
||||
f.remove();
|
||||
emit failed(index_within_job);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
QFile jar_file(m_target_path);
|
||||
|
||||
if (!jar_file.open(QIODevice::ReadOnly))
|
||||
@ -263,10 +277,10 @@ void ForgeXzDownload::decompressAndInstall()
|
||||
return;
|
||||
}
|
||||
m_entry->md5sum = QCryptographicHash::hash(jar_file.readAll(), QCryptographicHash::Md5)
|
||||
.toHex()
|
||||
.constData();
|
||||
.toHex()
|
||||
.constData();
|
||||
jar_file.close();
|
||||
|
||||
|
||||
QFileInfo output_file_info(m_target_path);
|
||||
m_entry->etag = m_reply->rawHeader("ETag").constData();
|
||||
m_entry->local_changed_timestamp =
|
||||
|
@ -1,3 +1,18 @@
|
||||
/* 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 "NetAction.h"
|
||||
|
@ -1,3 +1,18 @@
|
||||
/* 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 "MultiMC.h"
|
||||
#include "HttpMetaCache.h"
|
||||
#include <pathutils.h>
|
||||
@ -9,7 +24,7 @@
|
||||
#include <QDateTime>
|
||||
#include <QCryptographicHash>
|
||||
|
||||
#include <logger/QsLog.h>
|
||||
#include "logger/QsLog.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
@ -20,14 +35,12 @@ QString MetaEntry::getFullPath()
|
||||
return PathCombine(MMC->metacache()->getBasePath(base), path);
|
||||
}
|
||||
|
||||
|
||||
HttpMetaCache::HttpMetaCache(QString path)
|
||||
:QObject()
|
||||
HttpMetaCache::HttpMetaCache(QString path) : QObject()
|
||||
{
|
||||
m_index_file = path;
|
||||
saveBatchingTimer.setSingleShot(true);
|
||||
saveBatchingTimer.setTimerType(Qt::VeryCoarseTimer);
|
||||
connect(&saveBatchingTimer,SIGNAL(timeout()),SLOT(SaveNow()));
|
||||
connect(&saveBatchingTimer, SIGNAL(timeout()), SLOT(SaveNow()));
|
||||
}
|
||||
|
||||
HttpMetaCache::~HttpMetaCache()
|
||||
@ -36,58 +49,61 @@ HttpMetaCache::~HttpMetaCache()
|
||||
SaveNow();
|
||||
}
|
||||
|
||||
MetaEntryPtr HttpMetaCache::getEntry ( QString base, QString resource_path )
|
||||
MetaEntryPtr HttpMetaCache::getEntry(QString base, QString resource_path)
|
||||
{
|
||||
// no base. no base path. can't store
|
||||
if(!m_entries.contains(base))
|
||||
if (!m_entries.contains(base))
|
||||
{
|
||||
// TODO: log problem
|
||||
return MetaEntryPtr();
|
||||
}
|
||||
EntryMap & map = m_entries[base];
|
||||
if(map.entry_list.contains(resource_path))
|
||||
EntryMap &map = m_entries[base];
|
||||
if (map.entry_list.contains(resource_path))
|
||||
{
|
||||
return map.entry_list[resource_path];
|
||||
}
|
||||
return MetaEntryPtr();
|
||||
}
|
||||
|
||||
MetaEntryPtr HttpMetaCache::resolveEntry ( QString base, QString resource_path, QString expected_etag )
|
||||
MetaEntryPtr HttpMetaCache::resolveEntry(QString base, QString resource_path,
|
||||
QString expected_etag)
|
||||
{
|
||||
auto entry = getEntry(base, resource_path);
|
||||
// it's not present? generate a default stale entry
|
||||
if(!entry)
|
||||
if (!entry)
|
||||
{
|
||||
return staleEntry(base, resource_path);
|
||||
}
|
||||
|
||||
auto & selected_base = m_entries[base];
|
||||
|
||||
auto &selected_base = m_entries[base];
|
||||
QString real_path = PathCombine(selected_base.base_path, resource_path);
|
||||
QFileInfo finfo(real_path);
|
||||
|
||||
|
||||
// is the file really there? if not -> stale
|
||||
if(!finfo.isFile() || !finfo.isReadable())
|
||||
if (!finfo.isFile() || !finfo.isReadable())
|
||||
{
|
||||
// if the file doesn't exist, we disown the entry
|
||||
selected_base.entry_list.remove(resource_path);
|
||||
return staleEntry(base, resource_path);
|
||||
}
|
||||
|
||||
if(!expected_etag.isEmpty() && expected_etag != entry->etag)
|
||||
|
||||
if (!expected_etag.isEmpty() && expected_etag != entry->etag)
|
||||
{
|
||||
// if the etag doesn't match expected, we disown the entry
|
||||
selected_base.entry_list.remove(resource_path);
|
||||
return staleEntry(base, resource_path);
|
||||
}
|
||||
|
||||
|
||||
// if the file changed, check md5sum
|
||||
qint64 file_last_changed = finfo.lastModified().toUTC().toMSecsSinceEpoch();
|
||||
if(file_last_changed != entry->local_changed_timestamp)
|
||||
if (file_last_changed != entry->local_changed_timestamp)
|
||||
{
|
||||
QFile input(real_path);
|
||||
input.open(QIODevice::ReadOnly);
|
||||
QString md5sum = QCryptographicHash::hash(input.readAll(), QCryptographicHash::Md5).toHex().constData();
|
||||
if(entry->md5sum != md5sum)
|
||||
QString md5sum = QCryptographicHash::hash(input.readAll(), QCryptographicHash::Md5)
|
||||
.toHex()
|
||||
.constData();
|
||||
if (entry->md5sum != md5sum)
|
||||
{
|
||||
selected_base.entry_list.remove(resource_path);
|
||||
return staleEntry(base, resource_path);
|
||||
@ -101,14 +117,15 @@ MetaEntryPtr HttpMetaCache::resolveEntry ( QString base, QString resource_path,
|
||||
return entry;
|
||||
}
|
||||
|
||||
bool HttpMetaCache::updateEntry ( MetaEntryPtr stale_entry )
|
||||
bool HttpMetaCache::updateEntry(MetaEntryPtr stale_entry)
|
||||
{
|
||||
if(!m_entries.contains(stale_entry->base))
|
||||
if (!m_entries.contains(stale_entry->base))
|
||||
{
|
||||
QLOG_ERROR() << "Cannot add entry with unknown base: " << stale_entry->base.toLocal8Bit();
|
||||
QLOG_ERROR() << "Cannot add entry with unknown base: "
|
||||
<< stale_entry->base.toLocal8Bit();
|
||||
return false;
|
||||
}
|
||||
if(stale_entry->stale)
|
||||
if (stale_entry->stale)
|
||||
{
|
||||
QLOG_ERROR() << "Cannot add stale entry: " << stale_entry->getFullPath().toLocal8Bit();
|
||||
return false;
|
||||
@ -127,10 +144,10 @@ MetaEntryPtr HttpMetaCache::staleEntry(QString base, QString resource_path)
|
||||
return MetaEntryPtr(foo);
|
||||
}
|
||||
|
||||
void HttpMetaCache::addBase ( QString base, QString base_root )
|
||||
void HttpMetaCache::addBase(QString base, QString base_root)
|
||||
{
|
||||
// TODO: report error
|
||||
if(m_entries.contains(base))
|
||||
if (m_entries.contains(base))
|
||||
return;
|
||||
// TODO: check if the base path is valid
|
||||
EntryMap foo;
|
||||
@ -138,57 +155,57 @@ void HttpMetaCache::addBase ( QString base, QString base_root )
|
||||
m_entries[base] = foo;
|
||||
}
|
||||
|
||||
QString HttpMetaCache::getBasePath ( QString base )
|
||||
QString HttpMetaCache::getBasePath(QString base)
|
||||
{
|
||||
if(m_entries.contains(base))
|
||||
if (m_entries.contains(base))
|
||||
{
|
||||
return m_entries[base].base_path;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
void HttpMetaCache::Load()
|
||||
{
|
||||
QFile index(m_index_file);
|
||||
if(!index.open(QIODevice::ReadOnly))
|
||||
if (!index.open(QIODevice::ReadOnly))
|
||||
return;
|
||||
|
||||
|
||||
QJsonDocument json = QJsonDocument::fromJson(index.readAll());
|
||||
if(!json.isObject())
|
||||
if (!json.isObject())
|
||||
return;
|
||||
auto root = json.object();
|
||||
// check file version first
|
||||
auto version_val =root.value("version");
|
||||
if(!version_val.isString())
|
||||
auto version_val = root.value("version");
|
||||
if (!version_val.isString())
|
||||
return;
|
||||
if(version_val.toString() != "1")
|
||||
if (version_val.toString() != "1")
|
||||
return;
|
||||
|
||||
|
||||
// read the entry array
|
||||
auto entries_val =root.value("entries");
|
||||
if(!entries_val.isArray())
|
||||
auto entries_val = root.value("entries");
|
||||
if (!entries_val.isArray())
|
||||
return;
|
||||
QJsonArray array = entries_val.toArray();
|
||||
for(auto element: array)
|
||||
for (auto element : array)
|
||||
{
|
||||
if(!element.isObject())
|
||||
if (!element.isObject())
|
||||
return;
|
||||
auto element_obj = element.toObject();
|
||||
QString base = element_obj.value("base").toString();
|
||||
if(!m_entries.contains(base))
|
||||
if (!m_entries.contains(base))
|
||||
continue;
|
||||
auto & entrymap = m_entries[base];
|
||||
auto &entrymap = m_entries[base];
|
||||
auto foo = new MetaEntry;
|
||||
foo->base = base;
|
||||
QString path = foo->path = element_obj.value("path").toString();
|
||||
foo->md5sum = element_obj.value("md5sum").toString();
|
||||
foo->etag = element_obj.value("etag").toString();
|
||||
foo->local_changed_timestamp = element_obj.value("last_changed_timestamp").toDouble();
|
||||
foo->remote_changed_timestamp = element_obj.value("remote_changed_timestamp").toString();
|
||||
foo->remote_changed_timestamp =
|
||||
element_obj.value("remote_changed_timestamp").toString();
|
||||
// presumed innocent until closer examination
|
||||
foo->stale = false;
|
||||
entrymap.entry_list[path] = MetaEntryPtr( foo );
|
||||
entrymap.entry_list[path] = MetaEntryPtr(foo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,33 +219,35 @@ void HttpMetaCache::SaveEventually()
|
||||
void HttpMetaCache::SaveNow()
|
||||
{
|
||||
QSaveFile tfile(m_index_file);
|
||||
if(!tfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
||||
if (!tfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
||||
return;
|
||||
QJsonObject toplevel;
|
||||
toplevel.insert("version",QJsonValue(QString("1")));
|
||||
toplevel.insert("version", QJsonValue(QString("1")));
|
||||
QJsonArray entriesArr;
|
||||
for(auto group : m_entries)
|
||||
for (auto group : m_entries)
|
||||
{
|
||||
for(auto entry : group.entry_list)
|
||||
for (auto entry : group.entry_list)
|
||||
{
|
||||
QJsonObject entryObj;
|
||||
entryObj.insert("base", QJsonValue(entry->base));
|
||||
entryObj.insert("path", QJsonValue(entry->path));
|
||||
entryObj.insert("md5sum", QJsonValue(entry->md5sum));
|
||||
entryObj.insert("etag", QJsonValue(entry->etag));
|
||||
entryObj.insert("last_changed_timestamp", QJsonValue(double(entry->local_changed_timestamp)));
|
||||
if(!entry->remote_changed_timestamp.isEmpty())
|
||||
entryObj.insert("remote_changed_timestamp", QJsonValue(entry->remote_changed_timestamp));
|
||||
entryObj.insert("last_changed_timestamp",
|
||||
QJsonValue(double(entry->local_changed_timestamp)));
|
||||
if (!entry->remote_changed_timestamp.isEmpty())
|
||||
entryObj.insert("remote_changed_timestamp",
|
||||
QJsonValue(entry->remote_changed_timestamp));
|
||||
entriesArr.append(entryObj);
|
||||
}
|
||||
}
|
||||
toplevel.insert("entries",entriesArr);
|
||||
toplevel.insert("entries", entriesArr);
|
||||
QJsonDocument doc(toplevel);
|
||||
QByteArray jsonData = doc.toJson();
|
||||
qint64 result = tfile.write(jsonData);
|
||||
if(result == -1)
|
||||
if (result == -1)
|
||||
return;
|
||||
if(result != jsonData.size())
|
||||
if (result != jsonData.size())
|
||||
return;
|
||||
tfile.commit();
|
||||
}
|
||||
|
@ -1,3 +1,18 @@
|
||||
/* 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 <QSharedPointer>
|
||||
|
@ -100,7 +100,9 @@ void LoginTask::processYggdrasilReply(QNetworkReply *reply)
|
||||
processReply(reply, &LoginTask::parseYggdrasilReply, &LoginTask::parseYggdrasilError);
|
||||
}
|
||||
|
||||
void LoginTask::processReply(QNetworkReply *reply, std::function<void (LoginTask*, QByteArray)> parser, std::function<QString (LoginTask*, QNetworkReply*)> errorHandler)
|
||||
void LoginTask::processReply(QNetworkReply *reply,
|
||||
std::function<void(LoginTask *, QByteArray)> parser,
|
||||
std::function<QString(LoginTask *, QNetworkReply *)> errorHandler)
|
||||
{
|
||||
if (netReply != reply)
|
||||
return;
|
||||
@ -147,7 +149,7 @@ QString LoginTask::parseLegacyError(QNetworkReply *reply)
|
||||
|
||||
case 503:
|
||||
return tr("The login servers are currently unavailable. Check "
|
||||
"http://help.mojang.com/ for more info.");
|
||||
"http://help.mojang.com/ for more info.");
|
||||
|
||||
default:
|
||||
QLOG_DEBUG() << "Login failed with QNetworkReply code:" << reply->error();
|
||||
@ -161,7 +163,8 @@ QString LoginTask::parseYggdrasilError(QNetworkReply *reply)
|
||||
QJsonParseError jsonError;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
|
||||
|
||||
// If there are JSON errors fall back to using the legacy error handling using HTTP status codes
|
||||
// If there are JSON errors fall back to using the legacy error handling using HTTP status
|
||||
// codes
|
||||
if (jsonError.error != QJsonParseError::NoError)
|
||||
{
|
||||
return parseLegacyError(reply);
|
||||
@ -174,10 +177,10 @@ QString LoginTask::parseYggdrasilError(QNetworkReply *reply)
|
||||
|
||||
QJsonObject root = jsonDoc.object();
|
||||
|
||||
//QString error = root.value("error").toString();
|
||||
// QString error = root.value("error").toString();
|
||||
QString errorMessage = root.value("errorMessage").toString();
|
||||
|
||||
if(errorMessage.isEmpty())
|
||||
if (errorMessage.isEmpty())
|
||||
{
|
||||
return parseLegacyError(reply);
|
||||
}
|
||||
@ -230,14 +233,14 @@ void LoginTask::yggdrasilLogin()
|
||||
"accessToken": "random access token", // hexadecimal
|
||||
"clientToken": "client identifier", // identical to the one received
|
||||
"availableProfiles": [ // only present if the agent field was received
|
||||
{
|
||||
"id": "profile identifier", // hexadecimal
|
||||
"name": "player name"
|
||||
}
|
||||
{
|
||||
"id": "profile identifier", // hexadecimal
|
||||
"name": "player name"
|
||||
}
|
||||
],
|
||||
"selectedProfile": { // only present if the agent field was received
|
||||
"id": "profile identifier",
|
||||
"name": "player name"
|
||||
"id": "profile identifier",
|
||||
"name": "player name"
|
||||
}
|
||||
}
|
||||
*/
|
||||
@ -264,7 +267,7 @@ void LoginTask::parseYggdrasilReply(QByteArray data)
|
||||
QString playerID;
|
||||
QString playerName;
|
||||
auto selectedProfile = root.value("selectedProfile");
|
||||
if(selectedProfile.isObject())
|
||||
if (selectedProfile.isObject())
|
||||
{
|
||||
auto selectedProfileO = selectedProfile.toObject();
|
||||
playerID = selectedProfileO.value("id").toString();
|
||||
@ -281,7 +284,7 @@ void LoginTask::parseYggdrasilReply(QByteArray data)
|
||||
QString client_id;
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
result = {uInfo.username, sessionID, playerName, playerID, accessToken};
|
||||
emitSucceeded();
|
||||
}
|
||||
|
@ -45,7 +45,8 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
protected slots:
|
||||
protected
|
||||
slots:
|
||||
void legacyLogin();
|
||||
void processLegacyReply(QNetworkReply *reply);
|
||||
void parseLegacyReply(QByteArray data);
|
||||
@ -56,7 +57,8 @@ protected slots:
|
||||
void parseYggdrasilReply(QByteArray data);
|
||||
QString parseYggdrasilError(QNetworkReply *reply);
|
||||
|
||||
void processReply(QNetworkReply *reply, std::function<void(LoginTask*, QByteArray)>, std::function<QString(LoginTask*, QNetworkReply*)>);
|
||||
void processReply(QNetworkReply *reply, std::function<void(LoginTask *, QByteArray)>,
|
||||
std::function<QString(LoginTask *, QNetworkReply *)>);
|
||||
|
||||
protected:
|
||||
void executeTask();
|
||||
|
@ -1,3 +1,18 @@
|
||||
/* 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 <QObject>
|
||||
@ -42,12 +57,14 @@ signals:
|
||||
void succeeded(int index);
|
||||
void failed(int index);
|
||||
|
||||
protected slots:
|
||||
protected
|
||||
slots:
|
||||
virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) = 0;
|
||||
virtual void downloadError(QNetworkReply::NetworkError error) = 0;
|
||||
virtual void downloadFinished() = 0;
|
||||
virtual void downloadReadyRead() = 0;
|
||||
|
||||
public slots:
|
||||
public
|
||||
slots:
|
||||
virtual void start() = 0;
|
||||
};
|
||||
|
@ -1,3 +1,18 @@
|
||||
/* 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 "NetJob.h"
|
||||
#include "pathutils.h"
|
||||
#include "MultiMC.h"
|
||||
@ -5,7 +20,7 @@
|
||||
#include "ByteArrayDownload.h"
|
||||
#include "CacheDownload.h"
|
||||
|
||||
#include <logger/QsLog.h>
|
||||
#include "logger/QsLog.h"
|
||||
|
||||
void NetJob::partSucceeded(int index)
|
||||
{
|
||||
@ -15,7 +30,7 @@ void NetJob::partSucceeded(int index)
|
||||
|
||||
num_succeeded++;
|
||||
QLOG_INFO() << m_job_name.toLocal8Bit() << "progress:" << num_succeeded << "/"
|
||||
<< downloads.size();
|
||||
<< downloads.size();
|
||||
emit filesProgress(num_succeeded, num_failed, downloads.size());
|
||||
|
||||
if (num_failed + num_succeeded == downloads.size())
|
||||
@ -50,7 +65,7 @@ void NetJob::partFailed(int index)
|
||||
else
|
||||
{
|
||||
QLOG_ERROR() << "Part" << index << "failed, restarting (" << downloads[index]->m_url
|
||||
<< ")";
|
||||
<< ")";
|
||||
// restart the job
|
||||
slot.failures++;
|
||||
downloads[index]->start();
|
||||
|
@ -1,3 +1,18 @@
|
||||
/* 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 <QtNetwork>
|
||||
#include <QLabel>
|
||||
@ -18,10 +33,9 @@ class NetJob : public ProgressProvider
|
||||
public:
|
||||
explicit NetJob(QString job_name) : ProgressProvider(), m_job_name(job_name) {};
|
||||
|
||||
template <typename T>
|
||||
bool addNetAction(T action)
|
||||
template <typename T> bool addNetAction(T action)
|
||||
{
|
||||
NetActionPtr base = std::static_pointer_cast<NetAction>(action);
|
||||
NetActionPtr base = std::static_pointer_cast<NetAction>(action);
|
||||
base->index_within_job = downloads.size();
|
||||
downloads.append(action);
|
||||
parts_progress.append(part_info());
|
||||
|
@ -1,6 +1,21 @@
|
||||
/* 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 "S3ListBucket.h"
|
||||
#include "MultiMC.h"
|
||||
#include <logger/QsLog.h>
|
||||
#include "logger/QsLog.h"
|
||||
#include <QUrlQuery>
|
||||
#include <qxmlstream.h>
|
||||
#include <QDomDocument>
|
||||
@ -123,7 +138,7 @@ void S3ListBucket::processValidReply()
|
||||
emit failed(index_within_job);
|
||||
return;
|
||||
}
|
||||
if(is_truncated)
|
||||
if (is_truncated)
|
||||
{
|
||||
current_marker = objects.last().Key;
|
||||
bytesSoFar += m_reply->size();
|
||||
|
@ -1,3 +1,18 @@
|
||||
/* 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 "NetAction.h"
|
||||
|
||||
|
Reference in New Issue
Block a user