From 69a9ca39ad0685663092a4455de3865715f0122e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Thu, 8 May 2014 19:05:07 +0200 Subject: Add builtin Minecraft versions for legacy --- logic/MinecraftVersion.h | 36 ++++++---- logic/OneSixFTBInstance.cpp | 1 + logic/OneSixInstance.cpp | 4 ++ logic/VersionFile.cpp | 17 +++-- logic/VersionFile.h | 5 +- logic/VersionFinal.cpp | 8 +-- logic/VersionFinal.h | 8 ++- logic/lists/MinecraftVersionList.cpp | 136 ++++++++++++++++++++++++++--------- logic/lists/MinecraftVersionList.h | 1 + 9 files changed, 154 insertions(+), 62 deletions(-) (limited to 'logic') diff --git a/logic/MinecraftVersion.h b/logic/MinecraftVersion.h index 6cbfebbe..61f803b5 100644 --- a/logic/MinecraftVersion.h +++ b/logic/MinecraftVersion.h @@ -21,44 +21,52 @@ struct MinecraftVersion : public BaseVersion { - /*! - * Gets the version's timestamp. - * This is primarily used for sorting versions in a list. - */ + /// The version's timestamp - this is primarily used for sorting versions in a list. qint64 timestamp; /// The URL that this version will be downloaded from. maybe. QString download_url; - /// extra features enabled for this Minecraft version. Mostly for compatibility - QSet features; - /// is this the latest version? bool is_latest = false; /// is this a snapshot? bool is_snapshot = false; + /// is this a built-in version that comes with MultiMC? + bool is_builtin = false; + + /// the human readable version name QString m_name; + /// the version ID. QString m_descriptor; + /// version traits. generally launcher business... + QSet m_traits; + + /// The main class this version uses (if any, can be empty). + QString m_mainClass; + + /// The applet class this version uses (if any, can be empty). + QString m_appletClass; + bool usesLegacyLauncher() { - return features.contains("legacy"); + return m_traits.contains("legacyLaunch") || m_traits.contains("aplhaLaunch"); } - virtual QString descriptor() + virtual QString descriptor() override { return m_descriptor; } - virtual QString name() + virtual QString name() override { return m_name; } - virtual QString typeString() const + virtual QString typeString() const override { if (is_latest && is_snapshot) { @@ -70,7 +78,11 @@ struct MinecraftVersion : public BaseVersion } else if(is_snapshot) { - return QObject::tr("Old snapshot"); + return QObject::tr("Snapshot"); + } + else if(is_builtin) + { + return QObject::tr("Museum piece"); } else { diff --git a/logic/OneSixFTBInstance.cpp b/logic/OneSixFTBInstance.cpp index 34118111..131dbde3 100644 --- a/logic/OneSixFTBInstance.cpp +++ b/logic/OneSixFTBInstance.cpp @@ -100,6 +100,7 @@ QDir OneSixFTBInstance::librariesPath() const { return QDir(MMC->settings()->get("FTBRoot").toString() + "/libraries"); } + QDir OneSixFTBInstance::versionsPath() const { return QDir(MMC->settings()->get("FTBRoot").toString() + "/versions"); diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp index a351a5be..67953f95 100644 --- a/logic/OneSixInstance.cpp +++ b/logic/OneSixInstance.cpp @@ -224,6 +224,10 @@ bool OneSixInstance::prepareForLaunch(AuthSessionPtr account, QString &launchScr launchScript += "cp " + versionsPath().absoluteFilePath(minecraftjarpath) + "\n"; } launchScript += "mainClass " + version->mainClass + "\n"; + if(!version->appletClass.isEmpty()) + { + launchScript += "appletClass " + version->appletClass + "\n"; + } // generic minecraft params for (auto param : processMinecraftArgs(account)) diff --git a/logic/VersionFile.cpp b/logic/VersionFile.cpp index 222750d4..87936b6a 100644 --- a/logic/VersionFile.cpp +++ b/logic/VersionFile.cpp @@ -163,13 +163,14 @@ VersionFilePtr VersionFile::fromJson(const QJsonDocument &doc, const QString &fi } readString("mainClass", out->mainClass); + readString("appletClass", out->appletClass); readString("processArguments", out->processArguments); readString("minecraftArguments", out->overwriteMinecraftArguments); readString("+minecraftArguments", out->addMinecraftArguments); readString("-minecraftArguments", out->removeMinecraftArguments); readString("type", out->type); - readString("releaseTime", out->releaseTime); - readString("time", out->time); + readString("releaseTime", out->versionReleaseTime); + readString("time", out->versionFileUpdateTime); readString("assets", out->assets); if (root.contains("minimumLauncherVersion")) @@ -404,6 +405,10 @@ void VersionFile::applyTo(VersionFinal *version) { version->mainClass = mainClass; } + if (!appletClass.isNull()) + { + version->appletClass = appletClass; + } if (!processArguments.isNull()) { if(isVanilla()) @@ -416,13 +421,13 @@ void VersionFile::applyTo(VersionFinal *version) { version->type = type; } - if (!releaseTime.isNull()) + if (!versionReleaseTime.isNull()) { - version->releaseTime = releaseTime; + version->versionReleaseTime = versionReleaseTime; } - if (!time.isNull()) + if (!versionFileUpdateTime.isNull()) { - version->time = time; + version->time = versionFileUpdateTime; } if (!assets.isNull()) { diff --git a/logic/VersionFile.h b/logic/VersionFile.h index 2332e6d4..ae0c58a0 100644 --- a/logic/VersionFile.h +++ b/logic/VersionFile.h @@ -118,13 +118,14 @@ public: /* data */ // QMap requirements; QString id; QString mainClass; + QString appletClass; QString overwriteMinecraftArguments; QString addMinecraftArguments; QString removeMinecraftArguments; QString processArguments; QString type; - QString releaseTime; - QString time; + QString versionReleaseTime; + QString versionFileUpdateTime; QString assets; int minimumLauncherVersion = -1; diff --git a/logic/VersionFinal.cpp b/logic/VersionFinal.cpp index 5bac4bcf..b8690740 100644 --- a/logic/VersionFinal.cpp +++ b/logic/VersionFinal.cpp @@ -42,13 +42,14 @@ void VersionFinal::clear() { id.clear(); time.clear(); - releaseTime.clear(); + versionReleaseTime.clear(); type.clear(); assets.clear(); processArguments.clear(); minecraftArguments.clear(); minimumLauncherVersion = 0xDEADBEAF; mainClass.clear(); + appletClass.clear(); libraries.clear(); tweakers.clear(); jarMods.clear(); @@ -426,10 +427,5 @@ void VersionFinal::finalize() }; finalizeArguments(vanillaMinecraftArguments, vanillaProcessArguments); finalizeArguments(minecraftArguments, processArguments); - // use legacy launch for this version if the version id is legacy - if(g_VersionFilterData.legacyLaunchWhitelist.contains(id)) - { - traits.insert("legacyLaunch"); - } } diff --git a/logic/VersionFinal.h b/logic/VersionFinal.h index f3bf9771..ceb90f57 100644 --- a/logic/VersionFinal.h +++ b/logic/VersionFinal.h @@ -91,7 +91,7 @@ public: /// Last updated time - as a string QString time; /// Release time - as a string - QString releaseTime; + QString versionReleaseTime; /// Release type - "release" or "snapshot" QString type; /// Assets type - "legacy" or a version ID @@ -125,7 +125,11 @@ public: * The main class to load first */ QString mainClass; - + /** + * The applet class, for some very old minecraft releases + */ + QString appletClass; + /// the list of libs - both active and inactive, native and java QList> libraries; diff --git a/logic/lists/MinecraftVersionList.cpp b/logic/lists/MinecraftVersionList.cpp index fb6daae8..cdf5fa77 100644 --- a/logic/lists/MinecraftVersionList.cpp +++ b/logic/lists/MinecraftVersionList.cpp @@ -16,6 +16,7 @@ #include "MinecraftVersionList.h" #include "MultiMC.h" #include "logic/net/URLConstants.h" +#include #include @@ -29,8 +30,14 @@ #include +inline QDateTime timeFromS3Time(QString str) +{ + return QDateTime::fromString(str, Qt::ISODate); +} + MinecraftVersionList::MinecraftVersionList(QObject *parent) : BaseVersionList(parent) { + loadBuiltinList(); } Task *MinecraftVersionList::getLoadTask() @@ -65,6 +72,66 @@ void MinecraftVersionList::sortInternal() qSort(m_vlist.begin(), m_vlist.end(), cmpVersions); } +void MinecraftVersionList::loadBuiltinList() +{ + // grab the version list data from internal resources. + QResource versionList(":/versions/minecraft.json"); + QFile filez(versionList.absoluteFilePath()); + filez.open(QIODevice::ReadOnly); + auto data = filez.readAll(); + + // parse the data as json + QJsonParseError jsonError; + QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); + QJsonObject root = jsonDoc.object(); + + // parse all the versions + for (const auto version : MMCJson::ensureArray(root.value("versions"))) + { + QJsonObject versionObj = version.toObject(); + QString versionID = versionObj.value("id").toString(""); + QString versionTimeStr = versionObj.value("releaseTime").toString(""); + QString versionTypeStr = versionObj.value("type").toString(""); + QSet traits; + if (versionObj.contains("+traits")) + { + for (auto traitVal : MMCJson::ensureArray(versionObj.value("+traits"))) + { + traits.insert(MMCJson::ensureString(traitVal)); + } + } + if (versionID.isEmpty() || versionTimeStr.isEmpty() || versionTypeStr.isEmpty()) + { + // FIXME: log this somewhere + continue; + } + // Parse the timestamp. + QDateTime versionTime = timeFromS3Time(versionTimeStr); + if (!versionTime.isValid()) + { + // FIXME: log this somewhere + continue; + } + // Get the download URL. + QString dlUrl = "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + versionID + "/"; + + // main class and applet class + QString mainClass = versionObj.value("type").toString(""); + QString appletClass = versionObj.value("type").toString(""); + + // Now, we construct the version object and add it to the list. + std::shared_ptr mcVersion(new MinecraftVersion()); + mcVersion->m_name = mcVersion->m_descriptor = versionID; + mcVersion->timestamp = versionTime.toMSecsSinceEpoch(); + mcVersion->download_url = dlUrl; + mcVersion->is_builtin = true; + mcVersion->m_appletClass = appletClass; + mcVersion->m_mainClass = mainClass; + mcVersion->m_traits = traits; + m_vlist.append(mcVersion); + } +} + void MinecraftVersionList::sort() { beginResetModel(); @@ -88,7 +155,21 @@ BaseVersionPtr MinecraftVersionList::getLatestStable() const void MinecraftVersionList::updateListData(QList versions) { beginResetModel(); - m_vlist = versions; + for (auto version : versions) + { + auto descr = version->descriptor(); + for (auto builtin_v : m_vlist) + { + if (descr == builtin_v->descriptor()) + { + goto SKIP_THIS_ONE; + } + } + m_vlist.append(version); + SKIP_THIS_ONE: + { + } + } m_loaded = true; sortInternal(); endResetModel(); @@ -103,11 +184,6 @@ inline QDomElement getDomElementByTagName(QDomElement parent, QString tagname) return QDomElement(); } -inline QDateTime timeFromS3Time(QString str) -{ - return QDateTime::fromString(str, Qt::ISODate); -} - MCVListLoadTask::MCVListLoadTask(MinecraftVersionList *vlist) { m_list = vlist; @@ -123,7 +199,8 @@ void MCVListLoadTask::executeTask() { setStatus(tr("Loading instance version list...")); auto worker = MMC->qnam(); - vlistReply = worker->get(QNetworkRequest(QUrl("http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + "versions.json"))); + vlistReply = worker->get(QNetworkRequest( + QUrl("http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + "versions.json"))); connect(vlistReply, SIGNAL(finished()), this, SLOT(list_downloaded())); } @@ -136,8 +213,10 @@ void MCVListLoadTask::list_downloaded() return; } + auto foo = vlistReply->readAll(); QJsonParseError jsonError; - QJsonDocument jsonDoc = QJsonDocument::fromJson(vlistReply->readAll(), &jsonError); + QLOG_INFO() << foo; + QJsonDocument jsonDoc = QJsonDocument::fromJson(foo, &jsonError); vlistReply->deleteLater(); if (jsonError.error != QJsonParseError::NoError) @@ -154,26 +233,18 @@ void MCVListLoadTask::list_downloaded() QJsonObject root = jsonDoc.object(); - // Get the ID of the latest release and the latest snapshot. - if (!root.value("latest").isObject()) + QString latestReleaseID = "INVALID"; + QString latestSnapshotID = "INVALID"; + try { - emitFailed("Error parsing version list JSON: version list is missing 'latest' object"); - return; + QJsonObject latest = MMCJson::ensureObject(root.value("latest")); + latestReleaseID = MMCJson::ensureString(latest.value("release")); + latestSnapshotID = MMCJson::ensureString(latest.value("snapshot")); } - - QJsonObject latest = root.value("latest").toObject(); - - QString latestReleaseID = latest.value("release").toString(""); - QString latestSnapshotID = latest.value("snapshot").toString(""); - if (latestReleaseID.isEmpty()) - { - emitFailed("Error parsing version list JSON: latest release field is missing"); - return; - } - if (latestSnapshotID.isEmpty()) + catch (MMCError &err) { - emitFailed("Error parsing version list JSON: latest snapshot field is missing"); - return; + QLOG_ERROR() + << tr("Error parsing version list JSON: couldn't determine latest versions"); } // Now, get the array of versions. @@ -186,22 +257,21 @@ void MCVListLoadTask::list_downloaded() QJsonArray versions = root.value("versions").toArray(); QList tempList; - for (int i = 0; i < versions.count(); i++) + for (auto version : versions) { bool is_snapshot = false; bool is_latest = false; - bool legacyLaunch = false; // Load the version info. - if (!versions[i].isObject()) + if (!version.isObject()) { // FIXME: log this somewhere continue; } - QJsonObject version = versions[i].toObject(); - QString versionID = version.value("id").toString(""); - QString versionTimeStr = version.value("releaseTime").toString(""); - QString versionTypeStr = version.value("type").toString(""); + QJsonObject versionObj = version.toObject(); + QString versionID = versionObj.value("id").toString(""); + QString versionTimeStr = versionObj.value("releaseTime").toString(""); + QString versionTypeStr = versionObj.value("type").toString(""); if (versionID.isEmpty() || versionTimeStr.isEmpty() || versionTypeStr.isEmpty()) { // FIXME: log this somewhere @@ -251,8 +321,6 @@ void MCVListLoadTask::list_downloaded() mcVersion->download_url = dlUrl; mcVersion->is_latest = is_latest; mcVersion->is_snapshot = is_snapshot; - if(legacyLaunch) - mcVersion->features.insert("legacy"); tempList.append(mcVersion); } m_list->updateListData(tempList); diff --git a/logic/lists/MinecraftVersionList.h b/logic/lists/MinecraftVersionList.h index 8f748d34..4698fd8f 100644 --- a/logic/lists/MinecraftVersionList.h +++ b/logic/lists/MinecraftVersionList.h @@ -31,6 +31,7 @@ class MinecraftVersionList : public BaseVersionList Q_OBJECT private: void sortInternal(); + void loadBuiltinList(); public: friend class MCVListLoadTask; -- cgit v1.2.3