diff options
Diffstat (limited to 'api/logic')
28 files changed, 198 insertions, 798 deletions
diff --git a/api/logic/CMakeLists.txt b/api/logic/CMakeLists.txt index db1a7dec..50c2cb6e 100644 --- a/api/logic/CMakeLists.txt +++ b/api/logic/CMakeLists.txt @@ -305,10 +305,6 @@ set(MINECRAFT_SOURCES minecraft/AssetsUtils.h minecraft/AssetsUtils.cpp - # Forge and all things forge related - minecraft/forge/ForgeXzDownload.h - minecraft/forge/ForgeXzDownload.cpp - # Skin upload utilities minecraft/SkinUpload.cpp minecraft/SkinUpload.h @@ -439,15 +435,14 @@ set(META_SOURCES ) set(FTB_SOURCES - modplatform/ftb/FtbPackFetchTask.h - modplatform/ftb/FtbPackFetchTask.cpp - modplatform/ftb/FtbPackInstallTask.h - modplatform/ftb/FtbPackInstallTask.cpp - - modplatform/ftb/FtbPrivatePackManager.h - modplatform/ftb/FtbPrivatePackManager.cpp - - modplatform/ftb/PackHelpers.h + modplatform/legacy_ftb/PackFetchTask.h + modplatform/legacy_ftb/PackFetchTask.cpp + modplatform/legacy_ftb/PackInstallTask.h + modplatform/legacy_ftb/PackInstallTask.cpp + modplatform/legacy_ftb/PrivatePackManager.h + modplatform/legacy_ftb/PrivatePackManager.cpp + + modplatform/legacy_ftb/PackHelpers.h ) set(FLAME_SOURCES @@ -456,8 +451,6 @@ set(FLAME_SOURCES modplatform/flame/PackManifest.cpp modplatform/flame/FileResolvingTask.h modplatform/flame/FileResolvingTask.cpp - modplatform/flame/UrlResolvingTask.h - modplatform/flame/UrlResolvingTask.cpp ) add_unit_test(Index @@ -498,7 +491,7 @@ set_target_properties(MultiMC_logic PROPERTIES CXX_VISIBILITY_PRESET hidden VISI generate_export_header(MultiMC_logic) # Link -target_link_libraries(MultiMC_logic xz-embedded MultiMC_unpack200 systeminfo MultiMC_quazip MultiMC_classparser ${NBT_NAME} ${ZLIB_LIBRARIES}) +target_link_libraries(MultiMC_logic systeminfo MultiMC_quazip MultiMC_classparser ${NBT_NAME} ${ZLIB_LIBRARIES}) target_link_libraries(MultiMC_logic Qt5::Core Qt5::Xml Qt5::Network Qt5::Concurrent) # Mark and export headers diff --git a/api/logic/Commandline.h b/api/logic/Commandline.h index 5f6e5510..1adfb79d 100644 --- a/api/logic/Commandline.h +++ b/api/logic/Commandline.h @@ -69,8 +69,8 @@ namespace ArgumentStyle { enum Enum { - Space, /**< --option=value */ - Equals, /**< --option value */ + Space, /**< --option value */ + Equals, /**< --option=value */ SpaceAndEquals, /**< --option[= ]value */ #ifdef Q_OS_WIN32 Default = Equals diff --git a/api/logic/Env.cpp b/api/logic/Env.cpp index 77546bbc..0d496d4e 100644 --- a/api/logic/Env.cpp +++ b/api/logic/Env.cpp @@ -97,6 +97,7 @@ void Env::initHttpMetaCache() m_metacache->addBase("liteloader", QDir("mods/liteloader").absolutePath()); m_metacache->addBase("general", QDir("cache").absolutePath()); m_metacache->addBase("FTBPacks", QDir("cache/FTBPacks").absolutePath()); + m_metacache->addBase("TwitchPacks", QDir("cache/TwitchPacks").absolutePath()); m_metacache->addBase("skins", QDir("accounts/skins").absolutePath()); m_metacache->addBase("root", QDir::currentPath()); m_metacache->addBase("translations", QDir("translations").absolutePath()); diff --git a/api/logic/InstanceCopyTask.cpp b/api/logic/InstanceCopyTask.cpp index a576a0fd..35adeaf9 100644 --- a/api/logic/InstanceCopyTask.cpp +++ b/api/logic/InstanceCopyTask.cpp @@ -5,9 +5,10 @@ #include "pathmatcher/RegexpMatcher.h" #include <QtConcurrentRun> -InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, bool copySaves) +InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, bool copySaves, bool keepPlaytime) { m_origInstance = origInstance; + m_keepPlaytime = keepPlaytime; if(!copySaves) { @@ -46,6 +47,9 @@ void InstanceCopyTask::copyFinished() InstancePtr inst(new NullInstance(m_globalSettings, instanceSettings, m_stagingPath)); inst->setName(m_instName); inst->setIconKey(m_instIcon); + if(!m_keepPlaytime) { + inst->resetTimePlayed(); + } emitSucceeded(); } diff --git a/api/logic/InstanceCopyTask.h b/api/logic/InstanceCopyTask.h index 8dd55b40..6465e92d 100644 --- a/api/logic/InstanceCopyTask.h +++ b/api/logic/InstanceCopyTask.h @@ -15,7 +15,7 @@ class MULTIMC_LOGIC_EXPORT InstanceCopyTask : public InstanceTask { Q_OBJECT public: - explicit InstanceCopyTask(InstancePtr origInstance, bool copySaves); + explicit InstanceCopyTask(InstancePtr origInstance, bool copySaves, bool keepPlaytime); protected: //! Entry point for tasks. @@ -28,4 +28,5 @@ private: /* data */ QFuture<bool> m_copyFuture; QFutureWatcher<bool> m_copyFutureWatcher; std::unique_ptr<IPathMatcher> m_matcher; + bool m_keepPlaytime; }; diff --git a/api/logic/Version.cpp b/api/logic/Version.cpp index 42eac669..6392a50f 100644 --- a/api/logic/Version.cpp +++ b/api/logic/Version.cpp @@ -78,7 +78,7 @@ void Version::parse() // FIXME: this is bad. versions can contain a lot more separators... QStringList parts = m_string.split('.'); - for (const auto part : parts) + for (const auto &part : parts) { m_sections.append(Section(part)); } diff --git a/api/logic/minecraft/ComponentUpdateTask.cpp b/api/logic/minecraft/ComponentUpdateTask.cpp index 15003160..84c0474c 100644 --- a/api/logic/minecraft/ComponentUpdateTask.cpp +++ b/api/logic/minecraft/ComponentUpdateTask.cpp @@ -451,13 +451,17 @@ static bool getTrivialComponentChanges(const ComponentIndex & index, const Requi auto & comp = (*compIter); if(comp->getVersion() != req.equalsVersion) { - if(comp->m_dependencyOnly) - { - decision = Decision::VersionNotSame; - } - else - { + if(comp->isCustom()) { decision = Decision::LockedVersionNotSame; + } else { + if(comp->m_dependencyOnly) + { + decision = Decision::VersionNotSame; + } + else + { + decision = Decision::LockedVersionNotSame; + } } break; } diff --git a/api/logic/minecraft/LaunchProfile.cpp b/api/logic/minecraft/LaunchProfile.cpp index c39bdf04..41705187 100644 --- a/api/logic/minecraft/LaunchProfile.cpp +++ b/api/logic/minecraft/LaunchProfile.cpp @@ -11,6 +11,7 @@ void LaunchProfile::clear() m_mainClass.clear(); m_appletClass.clear(); m_libraries.clear(); + m_mavenFiles.clear(); m_traits.clear(); m_jarMods.clear(); m_mainJar.reset(); @@ -157,6 +158,22 @@ void LaunchProfile::applyLibrary(LibraryPtr library) } } +void LaunchProfile::applyMavenFile(LibraryPtr mavenFile) +{ + if(!mavenFile->isActive()) + { + return; + } + + if(mavenFile->isNative()) + { + return; + } + + // unlike libraries, we do not keep only one version or try to dedupe them + m_mavenFiles.append(Library::limitedCopy(mavenFile)); +} + const LibraryPtr LaunchProfile::getMainJar() const { return m_mainJar; @@ -253,6 +270,11 @@ const QList<LibraryPtr> & LaunchProfile::getNativeLibraries() const return m_nativeLibraries; } +const QList<LibraryPtr> & LaunchProfile::getMavenFiles() const +{ + return m_mavenFiles; +} + void LaunchProfile::getLibraryFiles( const QString& architecture, QStringList& jars, diff --git a/api/logic/minecraft/LaunchProfile.h b/api/logic/minecraft/LaunchProfile.h index 77174079..c1752531 100644 --- a/api/logic/minecraft/LaunchProfile.h +++ b/api/logic/minecraft/LaunchProfile.h @@ -20,6 +20,7 @@ public: /* application of profile variables from patches */ void applyJarMods(const QList<LibraryPtr> &jarMods); void applyMods(const QList<LibraryPtr> &jarMods); void applyLibrary(LibraryPtr library); + void applyMavenFile(LibraryPtr library); void applyMainJar(LibraryPtr jar); void applyProblemSeverity(ProblemSeverity severity); /// clear the profile @@ -37,6 +38,7 @@ public: /* getters for profile variables */ const QList<LibraryPtr> & getJarMods() const; const QList<LibraryPtr> & getLibraries() const; const QList<LibraryPtr> & getNativeLibraries() const; + const QList<LibraryPtr> & getMavenFiles() const; const LibraryPtr getMainJar() const; void getLibraryFiles( const QString & architecture, @@ -79,10 +81,13 @@ private: /// the list of libraries QList<LibraryPtr> m_libraries; + /// the list of maven files to be placed in the libraries folder, but not acted upon + QList<LibraryPtr> m_mavenFiles; + /// the main jar LibraryPtr m_mainJar; - /// the list of libraries + /// the list of native libraries QList<LibraryPtr> m_nativeLibraries; /// traits, collected from all the version files (version files can only add) diff --git a/api/logic/minecraft/Library.cpp b/api/logic/minecraft/Library.cpp index a56e8110..9ff8dcdc 100644 --- a/api/logic/minecraft/Library.cpp +++ b/api/logic/minecraft/Library.cpp @@ -3,7 +3,6 @@ #include <net/Download.h> #include <net/ChecksumValidator.h> -#include <minecraft/forge/ForgeXzDownload.h> #include <Env.h> #include <FileSystem.h> @@ -88,26 +87,19 @@ QList< std::shared_ptr< NetAction > > Library::getDownloads( { options |= Net::Download::Option::AcceptLocalFiles; } - if (isForge()) + + if(sha1.size()) { - qDebug() << "XzDownload for:" << rawName() << "storage:" << storage << "url:" << url; - out.append(ForgeXzDownload::make(url, storage, entry)); + auto rawSha1 = QByteArray::fromHex(sha1.toLatin1()); + auto dl = Net::Download::makeCached(url, entry, options); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1)); + qDebug() << "Checksummed Download for:" << rawName() << "storage:" << storage << "url:" << url; + out.append(dl); } else { - if(sha1.size()) - { - auto rawSha1 = QByteArray::fromHex(sha1.toLatin1()); - auto dl = Net::Download::makeCached(url, entry, options); - dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1)); - qDebug() << "Checksummed Download for:" << rawName() << "storage:" << storage << "url:" << url; - out.append(dl); - } - else - { - out.append(Net::Download::makeCached(url, entry, options)); - qDebug() << "Download for:" << rawName() << "storage:" << storage << "url:" << url; - } + out.append(Net::Download::makeCached(url, entry, options)); + qDebug() << "Download for:" << rawName() << "storage:" << storage << "url:" << url; } return true; }; @@ -243,11 +235,6 @@ bool Library::isAlwaysStale() const return m_hint == "always-stale"; } -bool Library::isForge() const -{ - return m_hint == "forge-pack-xz"; -} - void Library::setStoragePrefix(QString prefix) { m_storagePrefix = prefix; diff --git a/api/logic/minecraft/MinecraftUpdate.cpp b/api/logic/minecraft/MinecraftUpdate.cpp index 00558e37..f9ff114d 100644 --- a/api/logic/minecraft/MinecraftUpdate.cpp +++ b/api/logic/minecraft/MinecraftUpdate.cpp @@ -14,7 +14,6 @@ */ #include "Env.h" -#include <minecraft/forge/ForgeXzDownload.h> #include "MinecraftUpdate.h" #include "MinecraftInstance.h" diff --git a/api/logic/minecraft/OneSixVersionFormat.cpp b/api/logic/minecraft/OneSixVersionFormat.cpp index 6f3b926b..a0b6fd0e 100644 --- a/api/logic/minecraft/OneSixVersionFormat.cpp +++ b/api/logic/minecraft/OneSixVersionFormat.cpp @@ -144,14 +144,14 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc } } - auto readLibs = [&](const char * which) + auto readLibs = [&](const char * which, QList<LibraryPtr> & out) { for (auto libVal : requireArray(root.value(which))) { QJsonObject libObj = requireObject(libVal); // parse the library auto lib = libraryFromJson(libObj, filename); - out->libraries.append(lib); + out.append(lib); } }; bool hasPlusLibs = root.contains("+libraries"); @@ -160,16 +160,20 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc { out->addProblem(ProblemSeverity::Warning, QObject::tr("Version file has both '+libraries' and 'libraries'. This is no longer supported.")); - readLibs("libraries"); - readLibs("+libraries"); + readLibs("libraries", out->libraries); + readLibs("+libraries", out->libraries); } else if (hasLibs) { - readLibs("libraries"); + readLibs("libraries", out->libraries); } else if(hasPlusLibs) { - readLibs("+libraries"); + readLibs("+libraries", out->libraries); + } + + if(root.contains("mavenFiles")) { + readLibs("mavenFiles", out->mavenFiles); } // if we have mainJar, just use it @@ -276,6 +280,15 @@ QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr &patch } root.insert("libraries", array); } + if (!patch->mavenFiles.isEmpty()) + { + QJsonArray array; + for (auto value: patch->mavenFiles) + { + array.append(OneSixVersionFormat::libraryToJson(value.get())); + } + root.insert("mavenFiles", array); + } if (!patch->jarMods.isEmpty()) { QJsonArray array; diff --git a/api/logic/minecraft/VersionFile.cpp b/api/logic/minecraft/VersionFile.cpp index cfb9e504..5bad57e9 100644 --- a/api/logic/minecraft/VersionFile.cpp +++ b/api/logic/minecraft/VersionFile.cpp @@ -41,6 +41,10 @@ void VersionFile::applyTo(LaunchProfile *profile) { profile->applyLibrary(library); } + for (auto mavenFile : mavenFiles) + { + profile->applyMavenFile(mavenFile); + } profile->applyProblemSeverity(getProblemSeverity()); } @@ -53,4 +57,4 @@ void VersionFile::applyTo(LaunchProfile *profile) throw MinecraftVersionMismatch(uid, dependsOnMinecraftVersion, theirVersion); } } -*/
\ No newline at end of file +*/ diff --git a/api/logic/minecraft/VersionFile.h b/api/logic/minecraft/VersionFile.h index 3dc9db96..29ddd0bc 100644 --- a/api/logic/minecraft/VersionFile.h +++ b/api/logic/minecraft/VersionFile.h @@ -75,6 +75,9 @@ public: /* data */ /// Mojang: list of libraries to add to the version QList<LibraryPtr> libraries; + /// MultiMC: list of maven files to put in the libraries folder, but not in classpath + QList<LibraryPtr> mavenFiles; + /// The main jar (Minecraft version library, normally) LibraryPtr mainJar; diff --git a/api/logic/minecraft/forge/ForgeXzDownload.cpp b/api/logic/minecraft/forge/ForgeXzDownload.cpp deleted file mode 100644 index c6465469..00000000 --- a/api/logic/minecraft/forge/ForgeXzDownload.cpp +++ /dev/null @@ -1,393 +0,0 @@ -/* Copyright 2013-2019 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 "Env.h" -#include "ForgeXzDownload.h" -#include <FileSystem.h> - -#include <QCryptographicHash> -#include <QFileInfo> -#include <QDateTime> -#include <QDir> -#include <QDebug> - -ForgeXzDownload::ForgeXzDownload(QString url, QString relative_path, MetaEntryPtr entry) : NetAction() -{ - m_entry = entry; - m_target_path = entry->getFullPath(); - m_pack200_xz_file.setFileTemplate("./dl_temp.XXXXXX"); - m_status = Job_NotStarted; - m_url_path = relative_path; - m_url = url + ".pack.xz"; -} - -void ForgeXzDownload::start() -{ - if(m_status == Job_Aborted) - { - qWarning() << "Attempt to start an aborted Download:" << m_url.toString(); - emit aborted(m_index_within_job); - return; - } - m_status = Job_InProgress; - if (!m_entry->isStale()) - { - m_status = Job_Finished; - emit succeeded(m_index_within_job); - return; - } - // can we actually create the real, final file? - if (!FS::ensureFilePathExists(m_target_path)) - { - m_status = Job_Failed; - emit failed(m_index_within_job); - return; - } - - qDebug() << "Downloading " << m_url.toString(); - QNetworkRequest request(m_url); - request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->getETag().toLatin1()); - request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)"); - - QNetworkReply *rep = ENV.qnam().get(request); - - m_reply.reset(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 ForgeXzDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) -{ - m_total_progress = bytesTotal; - m_progress = bytesReceived; - emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal); -} - -void ForgeXzDownload::downloadError(QNetworkReply::NetworkError error) -{ - if(error == QNetworkReply::OperationCanceledError) - { - qCritical() << "Aborted " << m_url.toString(); - m_status = Job_Aborted; - } - else - { - // error happened during download. - qCritical() << "Failed " << m_url.toString() << " with reason " << error; - m_status = Job_Failed; - } -} - -void ForgeXzDownload::failAndTryNextMirror() -{ - m_status = Job_Failed; - emit failed(m_index_within_job); -} - -void ForgeXzDownload::downloadFinished() -{ - // if the download succeeded - if (m_status != Job_Failed && m_status != Job_Aborted) - { - // nothing went wrong... - m_status = Job_Finished; - if (m_pack200_xz_file.isOpen()) - { - // we actually downloaded something! process and isntall it - decompressAndInstall(); - return; - } - else - { - // something bad happened -- on the local machine! - m_status = Job_Failed; - m_pack200_xz_file.remove(); - m_reply.reset(); - emit failed(m_index_within_job); - return; - } - } - else if(m_status == Job_Aborted) - { - m_pack200_xz_file.remove(); - m_reply.reset(); - emit failed(m_index_within_job); - emit aborted(m_index_within_job); - return; - } - // else the download failed - else - { - m_status = Job_Failed; - m_pack200_xz_file.close(); - m_pack200_xz_file.remove(); - m_reply.reset(); - failAndTryNextMirror(); - return; - } -} - -void ForgeXzDownload::downloadReadyRead() -{ - - if (!m_pack200_xz_file.isOpen()) - { - if (!m_pack200_xz_file.open()) - { - /* - * Can't open the file... the job failed - */ - m_reply->abort(); - emit failed(m_index_within_job); - return; - } - } - m_pack200_xz_file.write(m_reply->readAll()); -} - -#include "xz.h" -#include "unpack200.h" -#include <stdexcept> -#include <unistd.h> - -const size_t buffer_size = 8196; - -// NOTE: once this gets here, it can't be aborted anymore. we don't care. -void ForgeXzDownload::decompressAndInstall() -{ - // rewind the downloaded temp file - m_pack200_xz_file.seek(0); - // de-xz'd file - QTemporaryFile pack200_file("./dl_temp.XXXXXX"); - pack200_file.open(); - - bool xz_success = false; - // first, de-xz - { - uint8_t in[buffer_size]; - uint8_t out[buffer_size]; - struct xz_buf b; - struct xz_dec *s; - enum xz_ret ret; - xz_crc32_init(); - xz_crc64_init(); - s = xz_dec_init(XZ_DYNALLOC, 1 << 26); - if (s == nullptr) - { - xz_dec_end(s); - failAndTryNextMirror(); - return; - } - b.in = in; - b.in_pos = 0; - b.in_size = 0; - b.out = out; - b.out_pos = 0; - b.out_size = buffer_size; - while (!xz_success) - { - if (b.in_pos == b.in_size) - { - b.in_size = m_pack200_xz_file.read((char *)in, sizeof(in)); - b.in_pos = 0; - } - - ret = xz_dec_run(s, &b); - - if (b.out_pos == sizeof(out)) - { - auto wresult = pack200_file.write((char *)out, b.out_pos); - if (wresult < 0 || size_t(wresult) != b.out_pos) - { - // msg = "Write error\n"; - xz_dec_end(s); - failAndTryNextMirror(); - return; - } - - b.out_pos = 0; - } - - if (ret == XZ_OK) - continue; - - if (ret == XZ_UNSUPPORTED_CHECK) - { - // unsupported check. this is OK, but we should log this - continue; - } - - auto wresult = pack200_file.write((char *)out, b.out_pos); - if (wresult < 0 || size_t(wresult) != b.out_pos) - { - // write error - pack200_file.close(); - xz_dec_end(s); - return; - } - - switch (ret) - { - case XZ_STREAM_END: - xz_dec_end(s); - xz_success = true; - break; - - case XZ_MEM_ERROR: - qCritical() << "Memory allocation failed\n"; - xz_dec_end(s); - failAndTryNextMirror(); - return; - - case XZ_MEMLIMIT_ERROR: - qCritical() << "Memory usage limit reached\n"; - xz_dec_end(s); - failAndTryNextMirror(); - return; - - case XZ_FORMAT_ERROR: - qCritical() << "Not a .xz file\n"; - xz_dec_end(s); - failAndTryNextMirror(); - return; - - case XZ_OPTIONS_ERROR: - qCritical() << "Unsupported options in the .xz headers\n"; - xz_dec_end(s); - failAndTryNextMirror(); - return; - - case XZ_DATA_ERROR: - case XZ_BUF_ERROR: - qCritical() << "File is corrupt\n"; - xz_dec_end(s); - failAndTryNextMirror(); - return; - - default: - qCritical() << "Bug!\n"; - xz_dec_end(s); - failAndTryNextMirror(); - return; - } - } - } - m_pack200_xz_file.remove(); - - // revert pack200 - pack200_file.seek(0); - int handle_in = pack200_file.handle(); - // FIXME: dispose of file handles, pointers and the like. Ideally wrap in objects. - if(handle_in == -1) - { - qCritical() << "Error reopening " << pack200_file.fileName(); - failAndTryNextMirror(); - return; - } - int handle_in_dup = dup (handle_in); - if(handle_in_dup == -1) - { - qCritical() << "Error reopening " << pack200_file.fileName(); - failAndTryNextMirror(); - return; - } - FILE *file_in = fdopen (handle_in_dup, "rb"); - if(!file_in) - { - qCritical() << "Error reopening " << pack200_file.fileName(); - failAndTryNextMirror(); - return; - } - QFile qfile_out(m_target_path); - if(!qfile_out.open(QIODevice::WriteOnly)) - { - qCritical() << "Error opening " << qfile_out.fileName(); - failAndTryNextMirror(); - return; - } - int handle_out = qfile_out.handle(); - if(handle_out == -1) - { - qCritical() << "Error opening " << qfile_out.fileName(); - failAndTryNextMirror(); - return; - } - int handle_out_dup = dup (handle_out); - if(handle_out_dup == -1) - { - qCritical() << "Error reopening " << qfile_out.fileName(); - failAndTryNextMirror(); - return; - } - FILE *file_out = fdopen (handle_out_dup, "wb"); - if(!file_out) - { - qCritical() << "Error opening " << qfile_out.fileName(); - failAndTryNextMirror(); - return; - } - try - { - // NOTE: this takes ownership of both FILE pointers. That's why we duplicate them above. - unpack_200(file_in, file_out); - } - catch (const std::runtime_error &err) - { - m_status = Job_Failed; - qCritical() << "Error unpacking " << pack200_file.fileName() << " : " << err.what(); - QFile f(m_target_path); - if (f.exists()) - f.remove(); - failAndTryNextMirror(); - return; - } - pack200_file.remove(); - - QFile jar_file(m_target_path); - - if (!jar_file.open(QIODevice::ReadOnly)) - { - jar_file.remove(); - failAndTryNextMirror(); - return; - } - auto hash = QCryptographicHash::hash(jar_file.readAll(), QCryptographicHash::Md5); - m_entry->setMD5Sum(hash.toHex().constData()); - jar_file.close(); - - QFileInfo output_file_info(m_target_path); - m_entry->setETag(m_reply->rawHeader("ETag").constData()); - m_entry->setLocalChangedTimestamp(output_file_info.lastModified().toUTC().toMSecsSinceEpoch()); - m_entry->setStale(false); - ENV.metacache()->updateEntry(m_entry); - - m_reply.reset(); - emit succeeded(m_index_within_job); -} - -bool ForgeXzDownload::abort() -{ - if(m_reply) - m_reply->abort(); - m_status = Job_Aborted; - return true; -} - -bool ForgeXzDownload::canAbort() -{ - return true; -} diff --git a/api/logic/minecraft/forge/ForgeXzDownload.h b/api/logic/minecraft/forge/ForgeXzDownload.h deleted file mode 100644 index 63e75f71..00000000 --- a/api/logic/minecraft/forge/ForgeXzDownload.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright 2013-2019 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/NetAction.h" -#include "net/HttpMetaCache.h" -#include <QFile> -#include <QTemporaryFile> - -typedef std::shared_ptr<class ForgeXzDownload> ForgeXzDownloadPtr; - -class ForgeXzDownload : public NetAction -{ - Q_OBJECT -public: - MetaEntryPtr m_entry; - /// if saving to file, use the one specified in this string - QString m_target_path; - /// this is the output file, if any - QTemporaryFile m_pack200_xz_file; - /// path relative to the mirror base - QString m_url_path; - -public: - explicit ForgeXzDownload(QString url, QString relative_path, MetaEntryPtr entry); - static ForgeXzDownloadPtr make(QString url, QString relative_path, MetaEntryPtr entry) - { - return ForgeXzDownloadPtr(new ForgeXzDownload(url, relative_path, entry)); - } - virtual ~ForgeXzDownload(){}; - bool canAbort() override; - -protected -slots: - void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override; - void downloadError(QNetworkReply::NetworkError error) override; - void downloadFinished() override; - void downloadReadyRead() override; - -public -slots: - void start() override; - bool abort() override; - -private: - void decompressAndInstall(); - void failAndTryNextMirror(); -}; diff --git a/api/logic/minecraft/mod/ModFolderModel.h b/api/logic/minecraft/mod/ModFolderModel.h index 8394e405..03c584a9 100644 --- a/api/logic/minecraft/mod/ModFolderModel.h +++ b/api/logic/minecraft/mod/ModFolderModel.h @@ -85,6 +85,10 @@ public: { return mods[index]; } + const Mod &at(size_t index) const + { + return mods.at(index); + } /// Reloads the mod list and returns true if the list changed. bool update(); diff --git a/api/logic/minecraft/update/LibrariesTask.cpp b/api/logic/minecraft/update/LibrariesTask.cpp index 912f492b..a000f77f 100644 --- a/api/logic/minecraft/update/LibrariesTask.cpp +++ b/api/logic/minecraft/update/LibrariesTask.cpp @@ -45,6 +45,7 @@ void LibrariesTask::executeTask() QList<LibraryPtr> libArtifactPool; libArtifactPool.append(profile->getLibraries()); libArtifactPool.append(profile->getNativeLibraries()); + libArtifactPool.append(profile->getMavenFiles()); libArtifactPool.append(profile->getMainJar()); processArtifactPool(libArtifactPool, failedLocalLibraries, inst->getLocalLibraryPath()); diff --git a/api/logic/modplatform/flame/UrlResolvingTask.cpp b/api/logic/modplatform/flame/UrlResolvingTask.cpp deleted file mode 100644 index 2a96f703..00000000 --- a/api/logic/modplatform/flame/UrlResolvingTask.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include "UrlResolvingTask.h" -#include <QtXml> -#include <Json.h> - - -namespace { - const char * metabase = "https://cursemeta.dries007.net"; -} - -Flame::UrlResolvingTask::UrlResolvingTask(const QString& toProcess) - : m_url(toProcess) -{ -} - -void Flame::UrlResolvingTask::executeTask() -{ - resolveUrl(); -} - -void Flame::UrlResolvingTask::resolveUrl() -{ - setStatus(tr("Resolving URL...")); - setProgress(0, 1); - QUrl actualUrl(m_url); - if(actualUrl.host() != "www.curseforge.com") { - emitFailed(tr("Not a Twitch URL.")); - return; - } - m_dljob.reset(new NetJob("URL resolver")); - - bool weAreDigging = false; - needle = QString(); - - if(m_url.startsWith("https://")) { - if(m_url.endsWith("?client=y")) { - // https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download?client=y - // https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download/2697088?client=y - m_url.chop(9); - // https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download - // https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download/2697088 - } - if(m_url.endsWith("/download")) { - // https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download -> need to dig inside html... - weAreDigging = true; - needle = m_url; - needle.replace("https://", "twitch://"); - needle.replace("/download", "/download-client/"); - m_url.append("?client=y"); - } else if (m_url.contains("/download/")) { - // https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download/2697088 - m_url.replace("/download/", "/download-client/"); - } - } - else if(m_url.startsWith("twitch://")) { - // twitch://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download-client/2697088 - m_url.replace(0, 9, "https://"); - // https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download-client/2697088 - } - auto dl = Net::Download::makeByteArray(QUrl(m_url), &results); - m_dljob->addNetAction(dl); - if(weAreDigging) { - connect(m_dljob.get(), &NetJob::finished, this, &Flame::UrlResolvingTask::processHTML); - } else { - connect(m_dljob.get(), &NetJob::finished, this, &Flame::UrlResolvingTask::processCCIP); - } - m_dljob->start(); -} - -void Flame::UrlResolvingTask::processHTML() -{ - QString htmlDoc = QString::fromUtf8(results); - auto index = htmlDoc.indexOf(needle); - if(index < 0) { - emitFailed(tr("Couldn't find the needle in the haystack...")); - return; - } - auto indexStart = index; - int indexEnd = -1; - while((index + 1) < htmlDoc.size() && htmlDoc[index] != '"') { - index ++; - if(htmlDoc[index] == '"') { - indexEnd = index; - break; - } - } - if(indexEnd > 0) { - QString found = htmlDoc.mid(indexStart, indexEnd - indexStart); - qDebug() << "Found needle: " << found; - // twitch://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download-client/2697088 - m_url = found; - resolveUrl(); - return; - } - emitFailed(tr("Couldn't find the end of the needle in the haystack...")); - return; -} - -void Flame::UrlResolvingTask::processCCIP() -{ - QDomDocument doc; - if (!doc.setContent(results)) { - qDebug() << results; - emitFailed(tr("Resolving failed.")); - return; - } - auto packageNode = doc.namedItem("package"); - if(!packageNode.isElement()) { - emitFailed(tr("Resolving failed: missing package root element.")); - return; - } - auto projectNode = packageNode.namedItem("project"); - if(!projectNode.isElement()) { - emitFailed(tr("Resolving failed: missing project element.")); - return; - } - auto attribs = projectNode.attributes(); - - auto projectIdNode = attribs.namedItem("id"); - if(!projectIdNode.isAttr()) { - emitFailed(tr("Resolving failed: missing id attribute.")); - return; - } - auto fileIdNode = attribs.namedItem("file"); - if(!fileIdNode.isAttr()) { - emitFailed(tr("Resolving failed: missing file attribute.")); - return; - } - - auto projectId = projectIdNode.nodeValue(); - auto fileId = fileIdNode.nodeValue(); - bool success = true; - m_result.projectId = projectId.toInt(&success); - if(!success) { - emitFailed(tr("Failed to resolve projectId as a number.")); - return; - } - m_result.fileId = fileId.toInt(&success); - if(!success) { - emitFailed(tr("Failed to resolve fileId as a number.")); - return; - } - qDebug() << "Resolved" << m_url << "as" << m_result.projectId << "/" << m_result.fileId; - resolveIDs(); -} - -void Flame::UrlResolvingTask::resolveIDs() -{ - setStatus(tr("Resolving mod IDs...")); - m_dljob.reset(new NetJob("Mod id resolver")); - auto projectIdStr = QString::number(m_result.projectId); - auto fileIdStr = QString::number(m_result.fileId); - QString metaurl = QString("%1/%2/%3.json").arg(metabase, projectIdStr, fileIdStr); - auto dl = Net::Download::makeByteArray(QUrl(metaurl), &results); - m_dljob->addNetAction(dl); - connect(m_dljob.get(), &NetJob::finished, this, &Flame::UrlResolvingTask::processCursemeta); - m_dljob->start(); -} - -void Flame::UrlResolvingTask::processCursemeta() -{ - try { - if(m_result.parseFromBytes(results)) { - emitSucceeded(); - qDebug() << results; - return; - } - } catch (const JSONValidationError &e) { - - qCritical() << "Resolving of" << m_result.projectId << m_result.fileId << "failed because of a parsing error:"; - qCritical() << e.cause(); - qCritical() << "JSON:"; - qCritical() << results; - } - emitFailed(tr("Failed to resolve the modpack file.")); -} diff --git a/api/logic/modplatform/flame/UrlResolvingTask.h b/api/logic/modplatform/flame/UrlResolvingTask.h deleted file mode 100644 index 98b78f67..00000000 --- a/api/logic/modplatform/flame/UrlResolvingTask.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "tasks/Task.h" -#include "net/NetJob.h" -#include "PackManifest.h" - -#include "multimc_logic_export.h" - -namespace Flame -{ -class MULTIMC_LOGIC_EXPORT UrlResolvingTask : public Task -{ - Q_OBJECT -public: - explicit UrlResolvingTask(const QString &toProcess); - virtual ~UrlResolvingTask() {}; - - const Flame::File &getResults() const - { - return m_result; - } - -protected: - virtual void executeTask() override; - -protected slots: - void processCCIP(); - void processHTML(); - void processCursemeta(); - -private: - void resolveUrl(); - void resolveIDs(); - -private: /* data */ - QString m_url; - QString needle; - Flame::File m_result; - QByteArray results; - NetJobPtr m_dljob; -}; -} - diff --git a/api/logic/modplatform/ftb/FtbPackFetchTask.cpp b/api/logic/modplatform/legacy_ftb/PackFetchTask.cpp index fe3f3fac..43c1e6f8 100644 --- a/api/logic/modplatform/ftb/FtbPackFetchTask.cpp +++ b/api/logic/modplatform/legacy_ftb/PackFetchTask.cpp @@ -1,34 +1,36 @@ -#include "FtbPackFetchTask.h" -#include <QDomDocument> -#include "FtbPrivatePackManager.h" +#include "PackFetchTask.h" +#include "PrivatePackManager.h" +#include <QDomDocument> #include "net/URLConstants.h" -void FtbPackFetchTask::fetch() +namespace LegacyFTB { + +void PackFetchTask::fetch() { publicPacks.clear(); thirdPartyPacks.clear(); - NetJob *netJob = new NetJob("FtbModpackFetch"); + NetJob *netJob = new NetJob("LegacyFTB::ModpackFetch"); - QUrl publicPacksUrl = QUrl(URLConstants::FTB_CDN_BASE_URL + "static/modpacks.xml"); + QUrl publicPacksUrl = QUrl(URLConstants::LEGACY_FTB_CDN_BASE_URL + "static/modpacks.xml"); qDebug() << "Downloading public version info from" << publicPacksUrl.toString(); netJob->addNetAction(Net::Download::makeByteArray(publicPacksUrl, &publicModpacksXmlFileData)); - QUrl thirdPartyUrl = QUrl(URLConstants::FTB_CDN_BASE_URL + "static/thirdparty.xml"); + QUrl thirdPartyUrl = QUrl(URLConstants::LEGACY_FTB_CDN_BASE_URL + "static/thirdparty.xml"); qDebug() << "Downloading thirdparty version info from" << thirdPartyUrl.toString(); netJob->addNetAction(Net::Download::makeByteArray(thirdPartyUrl, &thirdPartyModpacksXmlFileData)); - QObject::connect(netJob, &NetJob::succeeded, this, &FtbPackFetchTask::fileDownloadFinished); - QObject::connect(netJob, &NetJob::failed, this, &FtbPackFetchTask::fileDownloadFailed); + QObject::connect(netJob, &NetJob::succeeded, this, &PackFetchTask::fileDownloadFinished); + QObject::connect(netJob, &NetJob::failed, this, &PackFetchTask::fileDownloadFailed); jobPtr.reset(netJob); netJob->start(); } -void FtbPackFetchTask::fetchPrivate(const QStringList & toFetch) +void PackFetchTask::fetchPrivate(const QStringList & toFetch) { - QString privatePackBaseUrl = URLConstants::FTB_CDN_BASE_URL + "static/%1.xml"; + QString privatePackBaseUrl = URLConstants::LEGACY_FTB_CDN_BASE_URL + "static/%1.xml"; for (auto &packCode: toFetch) { @@ -38,9 +40,9 @@ void FtbPackFetchTask::fetchPrivate(const QStringList & toFetch) QObject::connect(job, &NetJob::succeeded, this, [this, job, data, packCode] { - FtbModpackList packs; - parseAndAddPacks(*data, FtbPackType::Private, packs); - foreach(FtbModpack currentPack, packs) + ModpackList packs; + parseAndAddPacks(*data, PackType::Private, packs); + foreach(Modpack currentPack, packs) { currentPack.packCode = packCode; emit privateFileDownloadFinished(currentPack); @@ -65,18 +67,18 @@ void FtbPackFetchTask::fetchPrivate(const QStringList & toFetch) } } -void FtbPackFetchTask::fileDownloadFinished() +void PackFetchTask::fileDownloadFinished() { jobPtr.reset(); QStringList failedLists; - if(!parseAndAddPacks(publicModpacksXmlFileData, FtbPackType::Public, publicPacks)) + if(!parseAndAddPacks(publicModpacksXmlFileData, PackType::Public, publicPacks)) { failedLists.append(tr("Public Packs")); } - if(!parseAndAddPacks(thirdPartyModpacksXmlFileData, FtbPackType::ThirdParty, thirdPartyPacks)) + if(!parseAndAddPacks(thirdPartyModpacksXmlFileData, PackType::ThirdParty, thirdPartyPacks)) { failedLists.append(tr("Third Party Packs")); } @@ -91,7 +93,7 @@ void FtbPackFetchTask::fileDownloadFinished() } } -bool FtbPackFetchTask::parseAndAddPacks(QByteArray &data, FtbPackType packType, FtbModpackList &list) +bool PackFetchTask::parseAndAddPacks(QByteArray &data, PackType packType, ModpackList &list) { QDomDocument doc; @@ -112,7 +114,7 @@ bool FtbPackFetchTask::parseAndAddPacks(QByteArray &data, FtbPackType packType, { QDomElement element = nodes.at(i).toElement(); - FtbModpack modpack; + Modpack modpack; modpack.name = element.attribute("name"); modpack.currentVersion = element.attribute("version"); modpack.mcVersion = element.attribute("mcVersion"); @@ -161,8 +163,10 @@ bool FtbPackFetchTask::parseAndAddPacks(QByteArray &data, FtbPackType packType, return true; } -void FtbPackFetchTask::fileDownloadFailed(QString reason) +void PackFetchTask::fileDownloadFailed(QString reason) { - qWarning() << "Fetching FtbPacks failed:" << reason; + qWarning() << "Fetching FTBPacks failed:" << reason; emit failed(reason); } + +} diff --git a/api/logic/modplatform/ftb/FtbPackFetchTask.h b/api/logic/modplatform/legacy_ftb/PackFetchTask.h index f955fe83..4a8469b1 100644 --- a/api/logic/modplatform/ftb/FtbPackFetchTask.h +++ b/api/logic/modplatform/legacy_ftb/PackFetchTask.h @@ -6,13 +6,15 @@ #include <QObject> #include "PackHelpers.h" -class MULTIMC_LOGIC_EXPORT FtbPackFetchTask : public QObject { +namespace LegacyFTB { + +class MULTIMC_LOGIC_EXPORT PackFetchTask : public QObject { Q_OBJECT public: - FtbPackFetchTask() = default; - virtual ~FtbPackFetchTask() = default; + PackFetchTask() = default; + virtual ~PackFetchTask() = default; void fetch(); void fetchPrivate(const QStringList &toFetch); @@ -23,18 +25,20 @@ private: QByteArray publicModpacksXmlFileData; QByteArray thirdPartyModpacksXmlFileData; - bool parseAndAddPacks(QByteArray &data, FtbPackType packType, FtbModpackList &list); - FtbModpackList publicPacks; - FtbModpackList thirdPartyPacks; + bool parseAndAddPacks(QByteArray &data, PackType packType, ModpackList &list); + ModpackList publicPacks; + ModpackList thirdPartyPacks; protected slots: void fileDownloadFinished(); void fileDownloadFailed(QString reason); signals: - void finished(FtbModpackList publicPacks, FtbModpackList thirdPartyPacks); + void finished(ModpackList publicPacks, ModpackList thirdPartyPacks); void failed(QString reason); - void privateFileDownloadFinished(FtbModpack modpack); + void privateFileDownloadFinished(Modpack modpack); void privateFileDownloadFailed(QString reason, QString packCode); }; + +} diff --git a/api/logic/modplatform/ftb/PackHelpers.h b/api/logic/modplatform/legacy_ftb/PackHelpers.h index 4306caee..566210d0 100644 --- a/api/logic/modplatform/ftb/PackHelpers.h +++ b/api/logic/modplatform/legacy_ftb/PackHelpers.h @@ -5,15 +5,17 @@ #include <QStringList> #include <QMetaType> +namespace LegacyFTB { + //Header for structs etc... -enum class FtbPackType +enum class PackType { Public, ThirdParty, Private }; -struct FtbModpack +struct Modpack { QString name; QString description; @@ -31,11 +33,13 @@ struct FtbModpack bool bugged = false; bool broken = false; - FtbPackType type; + PackType type; QString packCode; }; -//We need it for the proxy model -Q_DECLARE_METATYPE(FtbModpack) +typedef QList<Modpack> ModpackList; -typedef QList<FtbModpack> FtbModpackList; +} + +//We need it for the proxy model +Q_DECLARE_METATYPE(LegacyFTB::Modpack) diff --git a/api/logic/modplatform/ftb/FtbPackInstallTask.cpp b/api/logic/modplatform/legacy_ftb/PackInstallTask.cpp index 4962bcac..ea7e2c0c 100644 --- a/api/logic/modplatform/ftb/FtbPackInstallTask.cpp +++ b/api/logic/modplatform/legacy_ftb/PackInstallTask.cpp @@ -1,28 +1,32 @@ -#include "FtbPackInstallTask.h" +#include "PackInstallTask.h" + #include "Env.h" #include "MMCZip.h" -#include "QtConcurrent" + #include "BaseInstance.h" #include "FileSystem.h" #include "settings/INISettingsObject.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/ComponentList.h" #include "minecraft/GradleSpecifier.h" - #include "net/URLConstants.h" -FtbPackInstallTask::FtbPackInstallTask(FtbModpack pack, QString version) +#include <QtConcurrent> + +namespace LegacyFTB { + +PackInstallTask::PackInstallTask(Modpack pack, QString version) { m_pack = pack; m_version = version; } -void FtbPackInstallTask::executeTask() +void PackInstallTask::executeTask() { downloadPack(); } -void FtbPackInstallTask::downloadPack() +void PackInstallTask::downloadPack() { setStatus(tr("Downloading zip for %1").arg(m_pack.name)); @@ -32,46 +36,46 @@ void FtbPackInstallTask::downloadPack() entry->setStale(true); QString url; - if(m_pack.type == FtbPackType::Private) + if(m_pack.type == PackType::Private) { - url = QString(URLConstants::FTB_CDN_BASE_URL + "privatepacks/%1").arg(packoffset); + url = QString(URLConstants::LEGACY_FTB_CDN_BASE_URL + "privatepacks/%1").arg(packoffset); } else { - url = QString(URLConstants::FTB_CDN_BASE_URL + "modpacks/%1").arg(packoffset); + url = QString(URLConstants::LEGACY_FTB_CDN_BASE_URL + "modpacks/%1").arg(packoffset); } job->addNetAction(Net::Download::makeCached(url, entry)); archivePath = entry->getFullPath(); netJobContainer.reset(job); - connect(job, &NetJob::succeeded, this, &FtbPackInstallTask::onDownloadSucceeded); - connect(job, &NetJob::failed, this, &FtbPackInstallTask::onDownloadFailed); - connect(job, &NetJob::progress, this, &FtbPackInstallTask::onDownloadProgress); + connect(job, &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded); + connect(job, &NetJob::failed, this, &PackInstallTask::onDownloadFailed); + connect(job, &NetJob::progress, this, &PackInstallTask::onDownloadProgress); job->start(); progress(1, 4); } -void FtbPackInstallTask::onDownloadSucceeded() +void PackInstallTask::onDownloadSucceeded() { abortable = false; unzip(); } -void FtbPackInstallTask::onDownloadFailed(QString reason) +void PackInstallTask::onDownloadFailed(QString reason) { abortable = false; emitFailed(reason); } -void FtbPackInstallTask::onDownloadProgress(qint64 current, qint64 total) +void PackInstallTask::onDownloadProgress(qint64 current, qint64 total) { abortable = true; progress(current, total * 4); setStatus(tr("Downloading zip for %1 (%2%)").arg(m_pack.name).arg(current / 10)); } -void FtbPackInstallTask::unzip() +void PackInstallTask::unzip() { progress(2, 4); setStatus(tr("Extracting modpack")); @@ -85,22 +89,22 @@ void FtbPackInstallTask::unzip() } m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/unzip"); - connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &FtbPackInstallTask::onUnzipFinished); - connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &FtbPackInstallTask::onUnzipCanceled); + connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &PackInstallTask::onUnzipFinished); + connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &PackInstallTask::onUnzipCanceled); m_extractFutureWatcher.setFuture(m_extractFuture); } -void FtbPackInstallTask::onUnzipFinished() +void PackInstallTask::onUnzipFinished() { install(); } -void FtbPackInstallTask::onUnzipCanceled() +void PackInstallTask::onUnzipCanceled() { emitAborted(); } -void FtbPackInstallTask::install() +void PackInstallTask::install() { progress(3, 4); setStatus(tr("Installing modpack")); @@ -197,7 +201,7 @@ void FtbPackInstallTask::install() emitSucceeded(); } -bool FtbPackInstallTask::abort() +bool PackInstallTask::abort() { if(abortable) { @@ -205,3 +209,5 @@ bool FtbPackInstallTask::abort() } return false; } + +}
\ No newline at end of file diff --git a/api/logic/modplatform/ftb/FtbPackInstallTask.h b/api/logic/modplatform/legacy_ftb/PackInstallTask.h index 3319025e..1eec1880 100644 --- a/api/logic/modplatform/ftb/FtbPackInstallTask.h +++ b/api/logic/modplatform/legacy_ftb/PackInstallTask.h @@ -6,15 +6,17 @@ #include "meta/Index.h" #include "meta/Version.h" #include "meta/VersionList.h" -#include "modplatform/ftb/PackHelpers.h" +#include "PackHelpers.h" -class MULTIMC_LOGIC_EXPORT FtbPackInstallTask : public InstanceTask +namespace LegacyFTB { + +class MULTIMC_LOGIC_EXPORT PackInstallTask : public InstanceTask { Q_OBJECT public: - explicit FtbPackInstallTask(FtbModpack pack, QString version); - virtual ~FtbPackInstallTask(){} + explicit PackInstallTask(Modpack pack, QString version); + virtual ~PackInstallTask(){} bool abort() override; @@ -43,6 +45,8 @@ private: /* data */ NetJobPtr netJobContainer; QString archivePath; - FtbModpack m_pack; + Modpack m_pack; QString m_version; }; + +} diff --git a/api/logic/modplatform/ftb/FtbPrivatePackManager.cpp b/api/logic/modplatform/legacy_ftb/PrivatePackManager.cpp index c3477cec..501e6003 100644 --- a/api/logic/modplatform/ftb/FtbPrivatePackManager.cpp +++ b/api/logic/modplatform/legacy_ftb/PrivatePackManager.cpp @@ -1,10 +1,12 @@ -#include "FtbPrivatePackManager.h" +#include "PrivatePackManager.h" #include <QDebug> #include "FileSystem.h" -void FtbPrivatePackManager::load() +namespace LegacyFTB { + +void PrivatePackManager::load() { try { @@ -18,7 +20,7 @@ void FtbPrivatePackManager::load() } } -void FtbPrivatePackManager::save() const +void PrivatePackManager::save() const { if(!dirty) { @@ -35,3 +37,5 @@ void FtbPrivatePackManager::save() const qWarning() << "Failed to write third party FTB pack codes to" << m_filename; } } + +} diff --git a/api/logic/modplatform/ftb/FtbPrivatePackManager.h b/api/logic/modplatform/legacy_ftb/PrivatePackManager.h index 388224d6..0232bac7 100644 --- a/api/logic/modplatform/ftb/FtbPrivatePackManager.h +++ b/api/logic/modplatform/legacy_ftb/PrivatePackManager.h @@ -5,10 +5,12 @@ #include <QFile> #include "multimc_logic_export.h" -class MULTIMC_LOGIC_EXPORT FtbPrivatePackManager +namespace LegacyFTB { + +class MULTIMC_LOGIC_EXPORT PrivatePackManager { public: - ~FtbPrivatePackManager() + ~PrivatePackManager() { save(); } @@ -38,3 +40,5 @@ private: QString m_filename = "private_packs.txt"; mutable bool dirty = false; }; + +} diff --git a/api/logic/net/URLConstants.h b/api/logic/net/URLConstants.h index 5ff0f794..ebc495bb 100644 --- a/api/logic/net/URLConstants.h +++ b/api/logic/net/URLConstants.h @@ -29,7 +29,8 @@ const QString IMGUR_BASE_URL("https://api.imgur.com/3/"); const QString FMLLIBS_OUR_BASE_URL("https://files.multimc.org/fmllibs/"); const QString FMLLIBS_FORGE_BASE_URL("https://files.minecraftforge.net/fmllibs/"); const QString TRANSLATIONS_BASE_URL("https://files.multimc.org/translations/"); -const QString FTB_CDN_BASE_URL("https://ftb.forgecdn.net/FTB2/"); + +const QString LEGACY_FTB_CDN_BASE_URL("https://dist.creeper.host/FTB2/"); QString getJarPath(QString version); QString getLegacyJarUrl(QString version); |