diff --git a/api/logic/Env.cpp b/api/logic/Env.cpp index 42a1cff7..71b49d95 100644 --- a/api/logic/Env.cpp +++ b/api/logic/Env.cpp @@ -100,7 +100,7 @@ void Env::initHttpMetaCache() m_metacache->addBase("FTBPacks", QDir("cache/FTBPacks").absolutePath()); m_metacache->addBase("ModpacksCHPacks", QDir("cache/ModpacksCHPacks").absolutePath()); m_metacache->addBase("TechnicPacks", QDir("cache/TechnicPacks").absolutePath()); - m_metacache->addBase("TwitchPacks", QDir("cache/TwitchPacks").absolutePath()); + m_metacache->addBase("FlamePacks", QDir("cache/FlamePacks").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/RWStorage.h b/api/logic/RWStorage.h index 5d792367..3028388e 100644 --- a/api/logic/RWStorage.h +++ b/api/logic/RWStorage.h @@ -1,6 +1,9 @@ #pragma once #include #include +#include +#include + template class RWStorage { diff --git a/api/logic/minecraft/GradleSpecifier.h b/api/logic/minecraft/GradleSpecifier.h index 959325c6..60e0a726 100644 --- a/api/logic/minecraft/GradleSpecifier.h +++ b/api/logic/minecraft/GradleSpecifier.h @@ -18,32 +18,35 @@ struct GradleSpecifier { /* org.gradle.test.classifiers : service : 1.0 : jdk15 @ jar - DEBUG 0 "org.gradle.test.classifiers:service:1.0:jdk15@jar" - DEBUG 1 "org.gradle.test.classifiers" - DEBUG 2 "service" - DEBUG 3 "1.0" - DEBUG 4 ":jdk15" - DEBUG 5 "jdk15" - DEBUG 6 "@jar" - DEBUG 7 "jar" + 0 "org.gradle.test.classifiers:service:1.0:jdk15@jar" + 1 "org.gradle.test.classifiers" + 2 "service" + 3 "1.0" + 4 "jdk15" + 5 "jar" */ - QRegExp matcher("([^:@]+):([^:@]+):([^:@]+)" "(:([^:@]+))?" "(@([^:@]+))?"); + QRegExp matcher("([^:@]+):([^:@]+):([^:@]+)" "(?::([^:@]+))?" "(?:@([^:@]+))?"); m_valid = matcher.exactMatch(value); + if(!m_valid) { + m_invalidValue = value; + return *this; + } auto elements = matcher.capturedTexts(); m_groupId = elements[1]; m_artifactId = elements[2]; m_version = elements[3]; - m_classifier = elements[5]; - if(!elements[7].isEmpty()) + m_classifier = elements[4]; + if(!elements[5].isEmpty()) { - m_extension = elements[7]; + m_extension = elements[5]; } return *this; } - operator QString() const + QString serialize() const { - if(!m_valid) - return "INVALID"; + if(!m_valid) { + return m_invalidValue; + } QString retval = m_groupId + ":" + m_artifactId + ":" + m_version; if(!m_classifier.isEmpty()) { @@ -57,6 +60,9 @@ struct GradleSpecifier } QString getFileName() const { + if(!m_valid) { + return QString(); + } QString filename = m_artifactId + '-' + m_version; if(!m_classifier.isEmpty()) { @@ -67,8 +73,9 @@ struct GradleSpecifier } QString toPath(const QString & filenameOverride = QString()) const { - if(!m_valid) - return "INVALID"; + if(!m_valid) { + return QString(); + } QString filename; if(filenameOverride.isEmpty()) { @@ -134,6 +141,7 @@ struct GradleSpecifier return true; } private: + QString m_invalidValue; QString m_groupId; QString m_artifactId; QString m_version; diff --git a/api/logic/minecraft/GradleSpecifier_test.cpp b/api/logic/minecraft/GradleSpecifier_test.cpp index f49ec718..0900c9d8 100644 --- a/api/logic/minecraft/GradleSpecifier_test.cpp +++ b/api/logic/minecraft/GradleSpecifier_test.cpp @@ -31,7 +31,7 @@ slots: { QFETCH(QString, through); - QString converted = GradleSpecifier(through); + QString converted = GradleSpecifier(through).serialize(); QCOMPARE(converted, through); } @@ -68,7 +68,8 @@ slots: GradleSpecifier spec(input); QVERIFY(!spec.valid()); - QCOMPARE(spec.operator QString(), QString("INVALID")); + QCOMPARE(spec.serialize(), input); + QCOMPARE(spec.toPath(), QString()); } }; diff --git a/api/logic/minecraft/Library.cpp b/api/logic/minecraft/Library.cpp index b3c7657c..f2293679 100644 --- a/api/logic/minecraft/Library.cpp +++ b/api/logic/minecraft/Library.cpp @@ -94,13 +94,13 @@ QList< std::shared_ptr< NetAction > > Library::getDownloads( 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; + qDebug() << "Checksummed Download for:" << rawName().serialize() << "storage:" << storage << "url:" << url; out.append(dl); } else { out.append(Net::Download::makeCached(url, entry, options)); - qDebug() << "Download for:" << rawName() << "storage:" << storage << "url:" << url; + qDebug() << "Download for:" << rawName().serialize() << "storage:" << storage << "url:" << url; } return true; }; @@ -145,7 +145,7 @@ QList< std::shared_ptr< NetAction > > Library::getDownloads( } else { - qDebug() << "Ignoring native library" << m_name << "because it has no classifier for current OS"; + qDebug() << "Ignoring native library" << m_name.serialize() << "because it has no classifier for current OS"; } } else @@ -157,7 +157,7 @@ QList< std::shared_ptr< NetAction > > Library::getDownloads( } else { - qDebug() << "Ignoring java library" << m_name << "because it has no artifact"; + qDebug() << "Ignoring java library" << m_name.serialize() << "because it has no artifact"; } } } diff --git a/api/logic/minecraft/Library_test.cpp b/api/logic/minecraft/Library_test.cpp index c3d6150d..75bb4db1 100644 --- a/api/logic/minecraft/Library_test.cpp +++ b/api/logic/minecraft/Library_test.cpp @@ -18,7 +18,8 @@ private: jsonFile.open(QIODevice::ReadOnly); auto data = jsonFile.readAll(); jsonFile.close(); - return MojangVersionFormat::libraryFromJson(QJsonDocument::fromJson(data).object(), file); + ProblemContainer problems; + return MojangVersionFormat::libraryFromJson(problems, QJsonDocument::fromJson(data).object(), file); } // get absolute path to expected storage, assuming default cache prefix QStringList getStorage(QString relative) diff --git a/api/logic/minecraft/MinecraftInstance.cpp b/api/logic/minecraft/MinecraftInstance.cpp index ab1f294e..e715a1e1 100644 --- a/api/logic/minecraft/MinecraftInstance.cpp +++ b/api/logic/minecraft/MinecraftInstance.cpp @@ -526,11 +526,23 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session) out << ""; } + auto settings = this->settings(); + bool nativeOpenAL = settings->get("UseNativeOpenAL").toBool(); + bool nativeGLFW = settings->get("UseNativeGLFW").toBool(); + if (nativeOpenAL || nativeGLFW) + { + if (nativeOpenAL) + out << "Using system OpenAL."; + if (nativeGLFW) + out << "Using system GLFW."; + out << ""; + } + // libraries and class path. { out << "Libraries:"; QStringList jars, nativeJars; - auto javaArchitecture = settings()->get("JavaArchitecture").toString(); + auto javaArchitecture = settings->get("JavaArchitecture").toString(); profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath(), binRoot()); auto printLibFile = [&](const QString & path) { @@ -616,14 +628,14 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session) out << ""; QString windowParams; - if (settings()->get("LaunchMaximized").toBool()) + if (settings->get("LaunchMaximized").toBool()) { out << "Window size: max (if available)"; } else { - auto width = settings()->get("MinecraftWinWidth").toInt(); - auto height = settings()->get("MinecraftWinHeight").toInt(); + auto width = settings->get("MinecraftWinWidth").toInt(); + auto height = settings->get("MinecraftWinHeight").toInt(); out << "Window size: " + QString::number(width) + " x " + QString::number(height); } out << ""; diff --git a/api/logic/minecraft/MojangVersionFormat.cpp b/api/logic/minecraft/MojangVersionFormat.cpp index 33d3c54c..f9cb2228 100644 --- a/api/logic/minecraft/MojangVersionFormat.cpp +++ b/api/logic/minecraft/MojangVersionFormat.cpp @@ -220,7 +220,7 @@ VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc { auto libObj = requireObject(libVal); - auto lib = MojangVersionFormat::libraryFromJson(libObj, filename); + auto lib = MojangVersionFormat::libraryFromJson(*out, libObj, filename); out->libraries.append(lib); } } @@ -283,14 +283,18 @@ QJsonDocument MojangVersionFormat::versionFileToJson(const VersionFilePtr &patch } } -LibraryPtr MojangVersionFormat::libraryFromJson(const QJsonObject &libObj, const QString &filename) +LibraryPtr MojangVersionFormat::libraryFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename) { LibraryPtr out(new Library()); if (!libObj.contains("name")) { throw JSONValidationError(filename + "contains a library that doesn't have a 'name' field"); } - out->m_name = libObj.value("name").toString(); + auto rawName = libObj.value("name").toString(); + out->m_name = rawName; + if(!out->m_name.valid()) { + problems.addProblem(ProblemSeverity::Error, QObject::tr("Library %1 name is broken and cannot be processed.").arg(rawName)); + } Bits::readString(libObj, "url", out->m_repositoryURL); if (libObj.contains("extract")) @@ -333,7 +337,7 @@ LibraryPtr MojangVersionFormat::libraryFromJson(const QJsonObject &libObj, const QJsonObject MojangVersionFormat::libraryToJson(Library *library) { QJsonObject libRoot; - libRoot.insert("name", (QString)library->m_name); + libRoot.insert("name", library->m_name.serialize()); if (!library->m_repositoryURL.isEmpty()) { libRoot.insert("url", library->m_repositoryURL); diff --git a/api/logic/minecraft/MojangVersionFormat.h b/api/logic/minecraft/MojangVersionFormat.h index 76c529e9..2871dae4 100644 --- a/api/logic/minecraft/MojangVersionFormat.h +++ b/api/logic/minecraft/MojangVersionFormat.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "multimc_logic_export.h" @@ -20,6 +21,6 @@ public: static QJsonDocument versionFileToJson(const VersionFilePtr &patch); // libraries - static LibraryPtr libraryFromJson(const QJsonObject &libObj, const QString &filename); + static LibraryPtr libraryFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename); static QJsonObject libraryToJson(Library *library); }; diff --git a/api/logic/minecraft/OneSixVersionFormat.cpp b/api/logic/minecraft/OneSixVersionFormat.cpp index 7ac9e2db..d6aaa790 100644 --- a/api/logic/minecraft/OneSixVersionFormat.cpp +++ b/api/logic/minecraft/OneSixVersionFormat.cpp @@ -13,9 +13,9 @@ static void readString(const QJsonObject &root, const QString &key, QString &var } } -LibraryPtr OneSixVersionFormat::libraryFromJson(const QJsonObject &libObj, const QString &filename) +LibraryPtr OneSixVersionFormat::libraryFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename) { - LibraryPtr out = MojangVersionFormat::libraryFromJson(libObj, filename); + LibraryPtr out = MojangVersionFormat::libraryFromJson(problems, libObj, filename); readString(libObj, "MMC-hint", out->m_hint); readString(libObj, "MMC-absulute_url", out->m_absoluteURL); readString(libObj, "MMC-absoluteUrl", out->m_absoluteURL); @@ -115,7 +115,7 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc { QJsonObject libObj = requireObject(libVal); // parse the jarmod - auto lib = OneSixVersionFormat::jarModFromJson(libObj, filename); + auto lib = OneSixVersionFormat::jarModFromJson(*out, libObj, filename); // and add to jar mods out->jarMods.append(lib); } @@ -126,7 +126,7 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc { QJsonObject libObj = requireObject(libVal); // parse the jarmod - auto lib = OneSixVersionFormat::plusJarModFromJson(libObj, filename, out->name); + auto lib = OneSixVersionFormat::plusJarModFromJson(*out, libObj, filename, out->name); // and add to jar mods out->jarMods.append(lib); } @@ -138,20 +138,20 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc { QJsonObject libObj = requireObject(libVal); // parse the jarmod - auto lib = OneSixVersionFormat::modFromJson(libObj, filename); + auto lib = OneSixVersionFormat::modFromJson(*out, libObj, filename); // and add to jar mods out->mods.append(lib); } } - auto readLibs = [&](const char * which, QList & out) + auto readLibs = [&](const char * which, QList & outList) { for (auto libVal : requireArray(root.value(which))) { QJsonObject libObj = requireObject(libVal); // parse the library - auto lib = libraryFromJson(libObj, filename); - out.append(lib); + auto lib = libraryFromJson(*out, libObj, filename); + outList.append(lib); } }; bool hasPlusLibs = root.contains("+libraries"); @@ -180,7 +180,7 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc if(root.contains("mainJar")) { QJsonObject libObj = requireObject(root, "mainJar"); - out->mainJar = libraryFromJson(libObj, filename); + out->mainJar = libraryFromJson(*out, libObj, filename); } // else reconstruct it from downloads and id ... if that's available else if(!out->minecraftVersion.isEmpty()) @@ -330,8 +330,12 @@ QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr &patch } } -LibraryPtr OneSixVersionFormat::plusJarModFromJson(const QJsonObject &libObj, const QString &filename, const QString &originalName) -{ +LibraryPtr OneSixVersionFormat::plusJarModFromJson( + ProblemContainer & problems, + const QJsonObject &libObj, + const QString &filename, + const QString &originalName +) { LibraryPtr out(new Library()); if (!libObj.contains("name")) { @@ -366,9 +370,9 @@ LibraryPtr OneSixVersionFormat::plusJarModFromJson(const QJsonObject &libObj, co return out; } -LibraryPtr OneSixVersionFormat::jarModFromJson(const QJsonObject& libObj, const QString& filename) +LibraryPtr OneSixVersionFormat::jarModFromJson(ProblemContainer & problems, const QJsonObject& libObj, const QString& filename) { - return libraryFromJson(libObj, filename); + return libraryFromJson(problems, libObj, filename); } @@ -377,9 +381,9 @@ QJsonObject OneSixVersionFormat::jarModtoJson(Library *jarmod) return libraryToJson(jarmod); } -LibraryPtr OneSixVersionFormat::modFromJson(const QJsonObject& libObj, const QString& filename) +LibraryPtr OneSixVersionFormat::modFromJson(ProblemContainer & problems, const QJsonObject& libObj, const QString& filename) { - return libraryFromJson(libObj, filename); + return libraryFromJson(problems, libObj, filename); } QJsonObject OneSixVersionFormat::modtoJson(Library *jarmod) diff --git a/api/logic/minecraft/OneSixVersionFormat.h b/api/logic/minecraft/OneSixVersionFormat.h index 14ae385c..1a091d88 100644 --- a/api/logic/minecraft/OneSixVersionFormat.h +++ b/api/logic/minecraft/OneSixVersionFormat.h @@ -4,6 +4,7 @@ #include #include #include +#include class OneSixVersionFormat { @@ -13,17 +14,17 @@ public: static QJsonDocument versionFileToJson(const VersionFilePtr &patch); // libraries - static LibraryPtr libraryFromJson(const QJsonObject &libObj, const QString &filename); + static LibraryPtr libraryFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename); static QJsonObject libraryToJson(Library *library); // DEPRECATED: old 'plus' jar mods generated by the application - static LibraryPtr plusJarModFromJson(const QJsonObject &libObj, const QString &filename, const QString &originalName); + static LibraryPtr plusJarModFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename, const QString &originalName); // new jar mods derived from libraries - static LibraryPtr jarModFromJson(const QJsonObject &libObj, const QString &filename); + static LibraryPtr jarModFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename); static QJsonObject jarModtoJson(Library * jarmod); // mods, also derived from libraries - static LibraryPtr modFromJson(const QJsonObject &libObj, const QString &filename); + static LibraryPtr modFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename); static QJsonObject modtoJson(Library * jarmod); }; diff --git a/api/logic/modplatform/flame/PackManifest.cpp b/api/logic/modplatform/flame/PackManifest.cpp index 1db0a161..b928fd16 100644 --- a/api/logic/modplatform/flame/PackManifest.cpp +++ b/api/logic/modplatform/flame/PackManifest.cpp @@ -21,7 +21,7 @@ static void loadMinecraftV1(Flame::Minecraft & m, QJsonObject & minecraft) // intended use is likely hardcoded in the 'Flame' client, the manifest says nothing m.libraries = Json::ensureString(minecraft, QString("libraries"), QString()); auto arr = Json::ensureArray(minecraft, "modLoaders", QJsonArray()); - for (const auto & item : arr) + for (QJsonValueRef item : arr) { auto obj = Json::requireObject(item); Flame::Modloader loader; @@ -38,7 +38,7 @@ static void loadManifestV1(Flame::Manifest & m, QJsonObject & manifest) m.version = Json::ensureString(manifest, QString("version"), QString()); m.author = Json::ensureString(manifest, QString("author"), "Anonymous Coward"); auto arr = Json::ensureArray(manifest, "files", QJsonArray()); - for (const auto & item : arr) + for (QJsonValueRef item : arr) { auto obj = Json::requireObject(item); Flame::File file; diff --git a/api/logic/modplatform/modpacksch/FTBPackManifest.cpp b/api/logic/modplatform/modpacksch/FTBPackManifest.cpp index 35626cb8..fd99d332 100644 --- a/api/logic/modplatform/modpacksch/FTBPackManifest.cpp +++ b/api/logic/modplatform/modpacksch/FTBPackManifest.cpp @@ -60,7 +60,7 @@ void ModpacksCH::loadModpack(ModpacksCH::Modpack & m, QJsonObject & obj) m.updated = Json::requireInteger(obj, "updated"); m.refreshed = Json::requireInteger(obj, "refreshed"); auto artArr = Json::requireArray(obj, "art"); - for (const auto & artRaw : artArr) + for (QJsonValueRef artRaw : artArr) { auto artObj = Json::requireObject(artRaw); ModpacksCH::Art art; @@ -68,7 +68,7 @@ void ModpacksCH::loadModpack(ModpacksCH::Modpack & m, QJsonObject & obj) m.art.append(art); } auto authorArr = Json::requireArray(obj, "authors"); - for (const auto & authorRaw : authorArr) + for (QJsonValueRef authorRaw : authorArr) { auto authorObj = Json::requireObject(authorRaw); ModpacksCH::Author author; @@ -76,7 +76,7 @@ void ModpacksCH::loadModpack(ModpacksCH::Modpack & m, QJsonObject & obj) m.authors.append(author); } auto versionArr = Json::requireArray(obj, "versions"); - for (const auto & versionRaw : versionArr) + for (QJsonValueRef versionRaw : versionArr) { auto versionObj = Json::requireObject(versionRaw); ModpacksCH::VersionInfo version; @@ -84,7 +84,7 @@ void ModpacksCH::loadModpack(ModpacksCH::Modpack & m, QJsonObject & obj) m.versions.append(version); } auto tagArr = Json::requireArray(obj, "tags"); - for (const auto & tagRaw : tagArr) + for (QJsonValueRef tagRaw : tagArr) { auto tagObj = Json::requireObject(tagRaw); ModpacksCH::Tag tag; @@ -132,7 +132,7 @@ void ModpacksCH::loadVersion(ModpacksCH::Version & m, QJsonObject & obj) auto specs = Json::requireObject(obj, "specs"); loadSpecs(m.specs, specs); auto targetArr = Json::requireArray(obj, "targets"); - for (const auto & targetRaw : targetArr) + for (QJsonValueRef targetRaw : targetArr) { auto versionObj = Json::requireObject(targetRaw); ModpacksCH::VersionTarget target; @@ -140,7 +140,7 @@ void ModpacksCH::loadVersion(ModpacksCH::Version & m, QJsonObject & obj) m.targets.append(target); } auto fileArr = Json::requireArray(obj, "files"); - for (const auto & fileRaw : fileArr) + for (QJsonValueRef fileRaw : fileArr) { auto fileObj = Json::requireObject(fileRaw); ModpacksCH::VersionFile file; diff --git a/application/CMakeLists.txt b/application/CMakeLists.txt index a81327e3..afd13574 100644 --- a/application/CMakeLists.txt +++ b/application/CMakeLists.txt @@ -145,11 +145,11 @@ SET(MULTIMC_SOURCES pages/modplatform/legacy_ftb/ListModel.h pages/modplatform/legacy_ftb/ListModel.cpp - pages/modplatform/twitch/TwitchData.h - pages/modplatform/twitch/TwitchModel.cpp - pages/modplatform/twitch/TwitchModel.h - pages/modplatform/twitch/TwitchPage.cpp - pages/modplatform/twitch/TwitchPage.h + pages/modplatform/flame/FlameData.h + pages/modplatform/flame/FlameModel.cpp + pages/modplatform/flame/FlameModel.h + pages/modplatform/flame/FlamePage.cpp + pages/modplatform/flame/FlamePage.h pages/modplatform/technic/TechnicModel.cpp pages/modplatform/technic/TechnicModel.h @@ -276,7 +276,7 @@ SET(MULTIMC_UIS pages/modplatform/atlauncher/AtlPage.ui pages/modplatform/ftb/FtbPage.ui pages/modplatform/legacy_ftb/Page.ui - pages/modplatform/twitch/TwitchPage.ui + pages/modplatform/flame/FlamePage.ui pages/modplatform/technic/TechnicPage.ui pages/modplatform/ImportPage.ui diff --git a/application/dialogs/NewInstanceDialog.cpp b/application/dialogs/NewInstanceDialog.cpp index d70cbffe..112e46ff 100644 --- a/application/dialogs/NewInstanceDialog.cpp +++ b/application/dialogs/NewInstanceDialog.cpp @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include @@ -124,17 +124,17 @@ void NewInstanceDialog::accept() QList NewInstanceDialog::getPages() { importPage = new ImportPage(this); - twitchPage = new TwitchPage(this); + flamePage = new FlamePage(this); auto technicPage = new TechnicPage(this); return { new VanillaPage(this), importPage, new AtlPage(this), + flamePage, new FtbPage(this), new LegacyFTB::Page(this), - technicPage, - twitchPage + technicPage }; } diff --git a/application/dialogs/NewInstanceDialog.h b/application/dialogs/NewInstanceDialog.h index 88ed00e5..f8d96dbf 100644 --- a/application/dialogs/NewInstanceDialog.h +++ b/application/dialogs/NewInstanceDialog.h @@ -29,7 +29,7 @@ class NewInstanceDialog; class PageContainer; class QDialogButtonBox; class ImportPage; -class TwitchPage; +class FlamePage; class NewInstanceDialog : public QDialog, public BasePageProvider { @@ -68,7 +68,7 @@ private: QString InstIconKey; ImportPage *importPage = nullptr; - TwitchPage *twitchPage = nullptr; + FlamePage *flamePage = nullptr; std::unique_ptr creationTask; bool importIcon = false; diff --git a/application/package/ubuntu/README.md b/application/package/ubuntu/README.md index 5c0f4eeb..892abd12 100644 --- a/application/package/ubuntu/README.md +++ b/application/package/ubuntu/README.md @@ -6,9 +6,9 @@ It contains a `.desktop` file, an icon, and a simple script that does the heavy This is also the source for the files in the [RPM package](../rpm). If you rename, create or delete files here, you'll likely also have to update the RPM spec file there. # How to build this? -You need dpkg utils. Rename the `multimc` folder to `multimc_1.3-1` and then run: +You need dpkg utils. Rename the `multimc` folder to `multimc_1.5-1` and then run: ``` -fakeroot dpkg-deb --build multimc_1.3-1 +fakeroot dpkg-deb --build multimc_1.5-1 ``` Replace the version with whatever is appropriate. diff --git a/application/package/ubuntu/multimc/DEBIAN/control b/application/package/ubuntu/multimc/DEBIAN/control index 509dfe3c..3e0f570c 100644 --- a/application/package/ubuntu/multimc/DEBIAN/control +++ b/application/package/ubuntu/multimc/DEBIAN/control @@ -1,5 +1,5 @@ Package: multimc -Version: 1.4-1 +Version: 1.5-1 Architecture: all Maintainer: Petr Mrázek Section: games diff --git a/application/pages/instance/GameOptionsPage.cpp b/application/pages/instance/GameOptionsPage.cpp index 5555fc79..782f2ab3 100644 --- a/application/pages/instance/GameOptionsPage.cpp +++ b/application/pages/instance/GameOptionsPage.cpp @@ -35,6 +35,3 @@ void GameOptionsPage::closedImpl() { // m_model->unobserve(); } - -#include "GameOptionsPage.moc" - diff --git a/application/pages/instance/WorldListPage.cpp b/application/pages/instance/WorldListPage.cpp index d18c5355..119cff3e 100644 --- a/application/pages/instance/WorldListPage.cpp +++ b/application/pages/instance/WorldListPage.cpp @@ -314,6 +314,7 @@ void WorldListPage::worldChanged(const QModelIndex ¤t, const QModelIndex & ui->actionRemove->setEnabled(enable); ui->actionCopy->setEnabled(enable); ui->actionRename->setEnabled(enable); + ui->actionDatapacks->setEnabled(enable); bool hasIcon = !index.data(WorldList::IconFileRole).isNull(); ui->actionReset_Icon->setEnabled(enable && hasIcon); } diff --git a/application/pages/modplatform/twitch/TwitchData.h b/application/pages/modplatform/flame/FlameData.h similarity index 90% rename from application/pages/modplatform/twitch/TwitchData.h rename to application/pages/modplatform/flame/FlameData.h index dd000b84..9245ba8a 100644 --- a/application/pages/modplatform/twitch/TwitchData.h +++ b/application/pages/modplatform/flame/FlameData.h @@ -3,7 +3,7 @@ #include #include -namespace Twitch { +namespace Flame { struct ModpackAuthor { QString name; @@ -35,4 +35,4 @@ struct Modpack }; } -Q_DECLARE_METATYPE(Twitch::Modpack) +Q_DECLARE_METATYPE(Flame::Modpack) diff --git a/application/pages/modplatform/twitch/TwitchModel.cpp b/application/pages/modplatform/flame/FlameModel.cpp similarity index 91% rename from application/pages/modplatform/twitch/TwitchModel.cpp rename to application/pages/modplatform/flame/FlameModel.cpp index 5c6c7858..6d9dbda7 100644 --- a/application/pages/modplatform/twitch/TwitchModel.cpp +++ b/application/pages/modplatform/flame/FlameModel.cpp @@ -1,4 +1,4 @@ -#include "TwitchModel.h" +#include "FlameModel.h" #include "MultiMC.h" #include @@ -10,7 +10,7 @@ #include #include -namespace Twitch { +namespace Flame { ListModel::ListModel(QObject *parent) : QAbstractListModel(parent) { @@ -99,8 +99,8 @@ void ListModel::requestLogo(QString logo, QString url) return; } - MetaEntryPtr entry = ENV.metacache()->resolveEntry("TwitchPacks", QString("logos/%1").arg(logo.section(".", 0, 0))); - NetJob *job = new NetJob(QString("Twitch Icon Download %1").arg(logo)); + MetaEntryPtr entry = ENV.metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0))); + NetJob *job = new NetJob(QString("Flame Icon Download %1").arg(logo)); job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); auto fullPath = entry->getFullPath(); @@ -127,7 +127,7 @@ void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallbac { if(m_logoMap.contains(logo)) { - callback(ENV.metacache()->resolveEntry("TwitchPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); + callback(ENV.metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); } else { @@ -158,7 +158,7 @@ void ListModel::fetchMore(const QModelIndex& parent) void ListModel::performPaginatedSearch() { - NetJob *netJob = new NetJob("Twitch::Search"); + NetJob *netJob = new NetJob("Flame::Search"); auto searchUrl = QString( "https://addons-ecs.forgesvc.net/api/v2/addon/search?" "categoryId=0&" @@ -198,14 +198,14 @@ void ListModel::searchWithTerm(const QString& term) performPaginatedSearch(); } -void Twitch::ListModel::searchRequestFinished() +void Flame::ListModel::searchRequestFinished() { jobPtr.reset(); QJsonParseError parse_error; QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); if(parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Twitch at " << parse_error.offset << " reason: " << parse_error.errorString(); + qWarning() << "Error while parsing JSON response from CurseForge at " << parse_error.offset << " reason: " << parse_error.errorString(); qWarning() << response; return; } @@ -263,11 +263,12 @@ void Twitch::ListModel::searchRequestFinished() } pack.latestFile.addonId = pack.addonId; pack.latestFile.fileId = id; - // FIXME: what to do when there's more than one, or there's no version? auto versionArray = file.value("gameVersion").toArray(); - if(versionArray.size() != 1) { + if(versionArray.size() < 1) { continue; } + + // pick the latest version supported pack.latestFile.mcVersion = versionArray[0].toString(); pack.latestFile.version = file.value("displayName").toString(); pack.latestFile.downloadUrl = file.value("downloadUrl").toString(); @@ -292,7 +293,7 @@ void Twitch::ListModel::searchRequestFinished() endInsertRows(); } -void Twitch::ListModel::searchRequestFailed(QString reason) +void Flame::ListModel::searchRequestFailed(QString reason) { jobPtr.reset(); diff --git a/application/pages/modplatform/twitch/TwitchModel.h b/application/pages/modplatform/flame/FlameModel.h similarity index 95% rename from application/pages/modplatform/twitch/TwitchModel.h rename to application/pages/modplatform/flame/FlameModel.h index ad355c64..b4dded76 100644 --- a/application/pages/modplatform/twitch/TwitchModel.h +++ b/application/pages/modplatform/flame/FlameModel.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -16,9 +15,9 @@ #include #include -#include "TwitchData.h" +#include "FlameData.h" -namespace Twitch { +namespace Flame { typedef QMap LogoMap; diff --git a/application/pages/modplatform/twitch/TwitchPage.cpp b/application/pages/modplatform/flame/FlamePage.cpp similarity index 69% rename from application/pages/modplatform/twitch/TwitchPage.cpp rename to application/pages/modplatform/flame/FlamePage.cpp index 1e9f9dbb..3889f15a 100644 --- a/application/pages/modplatform/twitch/TwitchPage.cpp +++ b/application/pages/modplatform/flame/FlamePage.cpp @@ -1,29 +1,29 @@ -#include "TwitchPage.h" -#include "ui_TwitchPage.h" +#include "FlamePage.h" +#include "ui_FlamePage.h" #include "MultiMC.h" #include "dialogs/NewInstanceDialog.h" #include -#include "TwitchModel.h" +#include "FlameModel.h" #include -TwitchPage::TwitchPage(NewInstanceDialog* dialog, QWidget *parent) - : QWidget(parent), ui(new Ui::TwitchPage), dialog(dialog) +FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget *parent) + : QWidget(parent), ui(new Ui::FlamePage), dialog(dialog) { ui->setupUi(this); - connect(ui->searchButton, &QPushButton::clicked, this, &TwitchPage::triggerSearch); + connect(ui->searchButton, &QPushButton::clicked, this, &FlamePage::triggerSearch); ui->searchEdit->installEventFilter(this); - model = new Twitch::ListModel(this); + model = new Flame::ListModel(this); ui->packView->setModel(model); - connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &TwitchPage::onSelectionChanged); + connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlamePage::onSelectionChanged); } -TwitchPage::~TwitchPage() +FlamePage::~FlamePage() { delete ui; } -bool TwitchPage::eventFilter(QObject* watched, QEvent* event) +bool FlamePage::eventFilter(QObject* watched, QEvent* event) { if (watched == ui->searchEdit && event->type() == QEvent::KeyPress) { QKeyEvent* keyEvent = static_cast(event); @@ -36,22 +36,22 @@ bool TwitchPage::eventFilter(QObject* watched, QEvent* event) return QWidget::eventFilter(watched, event); } -bool TwitchPage::shouldDisplay() const +bool FlamePage::shouldDisplay() const { return true; } -void TwitchPage::openedImpl() +void FlamePage::openedImpl() { suggestCurrent(); } -void TwitchPage::triggerSearch() +void FlamePage::triggerSearch() { model->searchWithTerm(ui->searchEdit->text()); } -void TwitchPage::onSelectionChanged(QModelIndex first, QModelIndex second) +void FlamePage::onSelectionChanged(QModelIndex first, QModelIndex second) { if(!first.isValid()) { @@ -63,7 +63,7 @@ void TwitchPage::onSelectionChanged(QModelIndex first, QModelIndex second) return; } - current = model->data(first, Qt::UserRole).value(); + current = model->data(first, Qt::UserRole).value(); QString text = ""; QString name = current.name; @@ -72,7 +72,7 @@ void TwitchPage::onSelectionChanged(QModelIndex first, QModelIndex second) else text = "" + name + ""; if (!current.authors.empty()) { - auto authorToStr = [](Twitch::ModpackAuthor & author) { + auto authorToStr = [](Flame::ModpackAuthor & author) { if(author.url.isEmpty()) { return author.name; } @@ -90,7 +90,7 @@ void TwitchPage::onSelectionChanged(QModelIndex first, QModelIndex second) suggestCurrent(); } -void TwitchPage::suggestCurrent() +void FlamePage::suggestCurrent() { if(!isOpened) { @@ -103,7 +103,7 @@ void TwitchPage::suggestCurrent() dialog->setSuggestedPack(current.name, new InstanceImportTask(current.latestFile.downloadUrl)); QString editedLogoName; - editedLogoName = "twitch_" + current.logoName.section(".", 0, 0); + editedLogoName = "curseforge_" + current.logoName.section(".", 0, 0); model->getLogo(current.logoName, current.logoUrl, [this, editedLogoName](QString logo) { dialog->setSuggestedIconFromFile(logo, editedLogoName); diff --git a/application/pages/modplatform/twitch/TwitchPage.h b/application/pages/modplatform/flame/FlamePage.h similarity index 75% rename from application/pages/modplatform/twitch/TwitchPage.h rename to application/pages/modplatform/flame/FlamePage.h index 093900ff..e50186f5 100644 --- a/application/pages/modplatform/twitch/TwitchPage.h +++ b/application/pages/modplatform/flame/FlamePage.h @@ -20,41 +20,41 @@ #include "pages/BasePage.h" #include #include "tasks/Task.h" -#include "TwitchData.h" +#include "FlameData.h" namespace Ui { -class TwitchPage; +class FlamePage; } class NewInstanceDialog; -namespace Twitch { +namespace Flame { class ListModel; } -class TwitchPage : public QWidget, public BasePage +class FlamePage : public QWidget, public BasePage { Q_OBJECT public: - explicit TwitchPage(NewInstanceDialog* dialog, QWidget *parent = 0); - virtual ~TwitchPage(); + explicit FlamePage(NewInstanceDialog* dialog, QWidget *parent = 0); + virtual ~FlamePage(); virtual QString displayName() const override { - return tr("Twitch"); + return tr("CurseForge"); } virtual QIcon icon() const override { - return MMC->getThemedIcon("twitch"); + return MMC->getThemedIcon("flame"); } virtual QString id() const override { - return "twitch"; + return "flame"; } virtual QString helpPage() const override { - return "Twitch-platform"; + return "Flame-platform"; } virtual bool shouldDisplay() const override; @@ -70,8 +70,8 @@ private slots: void onSelectionChanged(QModelIndex first, QModelIndex second); private: - Ui::TwitchPage *ui = nullptr; + Ui::FlamePage *ui = nullptr; NewInstanceDialog* dialog = nullptr; - Twitch::ListModel* model = nullptr; - Twitch::Modpack current; + Flame::ListModel* model = nullptr; + Flame::Modpack current; }; diff --git a/application/pages/modplatform/twitch/TwitchPage.ui b/application/pages/modplatform/flame/FlamePage.ui similarity index 62% rename from application/pages/modplatform/twitch/TwitchPage.ui rename to application/pages/modplatform/flame/FlamePage.ui index c78d8ce0..21e23f1f 100644 --- a/application/pages/modplatform/twitch/TwitchPage.ui +++ b/application/pages/modplatform/flame/FlamePage.ui @@ -1,7 +1,7 @@ - TwitchPage - + FlamePage + 0 @@ -10,34 +10,36 @@ 745 - - - - - - - - Search - + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Search + + + + - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - + Qt::ScrollBarAlwaysOff @@ -53,6 +55,22 @@ + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + diff --git a/application/pages/modplatform/ftb/FtbListModel.cpp b/application/pages/modplatform/ftb/FtbListModel.cpp index 63236827..98973f2e 100644 --- a/application/pages/modplatform/ftb/FtbListModel.cpp +++ b/application/pages/modplatform/ftb/FtbListModel.cpp @@ -106,21 +106,22 @@ void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallbac void ListModel::searchWithTerm(const QString &term) { - if(currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull()) { + if(searchState != Failed && currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull()) { + // unless the search has failed, then there is no need to perform an identical search. return; } currentSearchTerm = term; + if(jobPtr) { jobPtr->abort(); - searchState = ResetRequested; - return; - } - else { - beginResetModel(); - modpacks.clear(); - endResetModel(); - searchState = None; + jobPtr.reset(); } + + beginResetModel(); + modpacks.clear(); + endResetModel(); + searchState = None; + performSearch(); } @@ -154,15 +155,7 @@ void ListModel::searchRequestFailed(QString reason) jobPtr.reset(); remainingPacks.clear(); - if(searchState == ResetRequested) { - beginResetModel(); - modpacks.clear(); - endResetModel(); - - performSearch(); - } else { - searchState = Finished; - } + searchState = Failed; } void ListModel::requestPack() diff --git a/application/pages/modplatform/ftb/FtbListModel.h b/application/pages/modplatform/ftb/FtbListModel.h index 9c057d73..de94e6ba 100644 --- a/application/pages/modplatform/ftb/FtbListModel.h +++ b/application/pages/modplatform/ftb/FtbListModel.h @@ -57,7 +57,8 @@ private: None, CanPossiblyFetchMore, ResetRequested, - Finished + Finished, + Failed, } searchState = None; NetJobPtr jobPtr; int currentPack; diff --git a/application/resources/multimc/multimc.qrc b/application/resources/multimc/multimc.qrc index 4e95869e..249e8e28 100644 --- a/application/resources/multimc/multimc.qrc +++ b/application/resources/multimc/multimc.qrc @@ -11,8 +11,9 @@ scalable/reddit-alien.svg - - scalable/twitch.svg + + 32x32/instances/flame.png + 128x128/instances/flame.png scalable/technic.svg diff --git a/application/resources/multimc/scalable/twitch.svg b/application/resources/multimc/scalable/twitch.svg deleted file mode 100644 index 80999380..00000000 --- a/application/resources/multimc/scalable/twitch.svg +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - image/svg+xml - - Glitch - - - - - - - - Glitch - -