summaryrefslogtreecommitdiffstats
path: root/logic/minecraft
diff options
context:
space:
mode:
Diffstat (limited to 'logic/minecraft')
-rw-r--r--logic/minecraft/AssetsUtils.cpp52
-rw-r--r--logic/minecraft/AssetsUtils.h12
-rw-r--r--logic/minecraft/MinecraftProfile.cpp22
-rw-r--r--logic/minecraft/MinecraftProfile.h9
-rw-r--r--logic/minecraft/MojangVersionFormat.cpp8
-rw-r--r--logic/minecraft/VersionFile.cpp2
-rw-r--r--logic/minecraft/onesix/OneSixInstance.cpp5
-rw-r--r--logic/minecraft/onesix/OneSixUpdate.cpp35
8 files changed, 95 insertions, 50 deletions
diff --git a/logic/minecraft/AssetsUtils.cpp b/logic/minecraft/AssetsUtils.cpp
index b3589cb8..7a525abe 100644
--- a/logic/minecraft/AssetsUtils.cpp
+++ b/logic/minecraft/AssetsUtils.cpp
@@ -13,6 +13,7 @@
* limitations under the License.
*/
+#include <QFileInfo>
#include <QDir>
#include <QDirIterator>
#include <QCryptographicHash>
@@ -23,7 +24,8 @@
#include <QDebug>
#include "AssetsUtils.h"
-#include <FileSystem.h>
+#include "FileSystem.h"
+#include "net/MD5EtagDownload.h"
namespace AssetsUtils
{
@@ -32,7 +34,7 @@ namespace AssetsUtils
* Returns true on success, with index populated
* index is undefined otherwise
*/
-bool loadAssetsIndexJson(QString path, AssetsIndex *index)
+bool loadAssetsIndexJson(QString assetsId, QString path, AssetsIndex *index)
{
/*
{
@@ -56,6 +58,7 @@ bool loadAssetsIndexJson(QString path, AssetsIndex *index)
qCritical() << "Failed to read assets index file" << path;
return false;
}
+ index->id = assetsId;
// Read the file and close it.
QByteArray jsonData = file.readAll();
@@ -143,7 +146,7 @@ QDir reconstructAssets(QString assetsId)
<< objectDir.path() << virtualDir.path() << virtualRoot.path();
AssetsIndex index;
- bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(indexPath, &index);
+ bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(assetsId, indexPath, &index);
if (loadAssetsIndex && index.isVirtual)
{
@@ -182,3 +185,46 @@ QDir reconstructAssets(QString assetsId)
}
}
+
+NetActionPtr AssetObject::getDownloadAction()
+{
+ QFileInfo objectFile(getLocalPath());
+ if ((!objectFile.isFile()) || (objectFile.size() != size))
+ {
+ auto objectDL = MD5EtagDownload::make(getUrl(), objectFile.filePath());
+ objectDL->m_total_progress = size;
+ return objectDL;
+ }
+ return nullptr;
+}
+
+QString AssetObject::getLocalPath()
+{
+ return "assets/objects/" + getRelPath();
+}
+
+QUrl AssetObject::getUrl()
+{
+ return QUrl("http://resources.download.minecraft.net/" + getRelPath());
+}
+
+QString AssetObject::getRelPath()
+{
+ return hash.left(2) + "/" + hash;
+}
+
+NetJobPtr AssetsIndex::getDownloadJob()
+{
+ auto job = new NetJob(QObject::tr("Assets for %1").arg(id));
+ for (auto &object : objects.values())
+ {
+ auto dl = object.getDownloadAction();
+ if(dl)
+ {
+ job->addNetAction(dl);
+ }
+ }
+ if(job->size())
+ return job;
+ return nullptr;
+}
diff --git a/logic/minecraft/AssetsUtils.h b/logic/minecraft/AssetsUtils.h
index 2aecd4c5..90251c2d 100644
--- a/logic/minecraft/AssetsUtils.h
+++ b/logic/minecraft/AssetsUtils.h
@@ -17,22 +17,32 @@
#include <QString>
#include <QMap>
+#include "net/NetAction.h"
+#include "net/NetJob.h"
struct AssetObject
{
+ QString getRelPath();
+ QUrl getUrl();
+ QString getLocalPath();
+ NetActionPtr getDownloadAction();
+
QString hash;
qint64 size;
};
struct AssetsIndex
{
+ NetJobPtr getDownloadJob();
+
+ QString id;
QMap<QString, AssetObject> objects;
bool isVirtual = false;
};
namespace AssetsUtils
{
-bool loadAssetsIndexJson(QString file, AssetsIndex* index);
+bool loadAssetsIndexJson(QString id, QString file, AssetsIndex* index);
/// Reconstruct a virtual assets folder for the given assets ID and return the folder
QDir reconstructAssets(QString assetsId);
}
diff --git a/logic/minecraft/MinecraftProfile.cpp b/logic/minecraft/MinecraftProfile.cpp
index 5fd700f2..71ece012 100644
--- a/logic/minecraft/MinecraftProfile.cpp
+++ b/logic/minecraft/MinecraftProfile.cpp
@@ -62,7 +62,7 @@ void MinecraftProfile::clear()
{
m_minecraftVersion.clear();
m_minecraftVersionType.clear();
- m_minecraftAssets.clear();
+ m_minecraftAssets.reset();
m_minecraftArguments.clear();
m_tweakers.clear();
m_mainClass.clear();
@@ -420,9 +420,12 @@ void MinecraftProfile::applyMinecraftVersionType(const QString& type)
applyString(type, this->m_minecraftVersionType);
}
-void MinecraftProfile::applyMinecraftAssets(const QString& assets)
+void MinecraftProfile::applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets)
{
- applyString(assets, this->m_minecraftAssets);
+ if(assets)
+ {
+ m_minecraftAssets = assets;
+ }
}
void MinecraftProfile::applyTraits(const QSet<QString>& traits)
@@ -544,18 +547,11 @@ QString MinecraftProfile::getMinecraftVersionType() const
return m_minecraftVersionType;
}
-QString MinecraftProfile::getMinecraftAssets() const
+std::shared_ptr<MojangAssetIndexInfo> MinecraftProfile::getMinecraftAssets() const
{
- // HACK: deny april fools. my head hurts enough already.
- QDate now = QDate::currentDate();
- bool isAprilFools = now.month() == 4 && now.day() == 1;
- if (m_minecraftAssets.endsWith("_af") && !isAprilFools)
- {
- return m_minecraftAssets.left(m_minecraftAssets.length() - 3);
- }
- if (m_minecraftAssets.isEmpty())
+ if(!m_minecraftAssets)
{
- return QLatin1Literal("legacy");
+ return std::make_shared<MojangAssetIndexInfo>("legacy");
}
return m_minecraftAssets;
}
diff --git a/logic/minecraft/MinecraftProfile.h b/logic/minecraft/MinecraftProfile.h
index 6e7e8f74..ce0ff3cf 100644
--- a/logic/minecraft/MinecraftProfile.h
+++ b/logic/minecraft/MinecraftProfile.h
@@ -24,6 +24,7 @@
#include "Library.h"
#include "VersionFile.h"
#include "JarMod.h"
+#include "MojangDownloadInfo.h"
#include "multimc_logic_export.h"
@@ -90,19 +91,19 @@ public: /* application of profile variables from patches */
void applyAppletClass(const QString& appletClass);
void applyMinecraftArguments(const QString& minecraftArguments);
void applyMinecraftVersionType(const QString& type);
- void applyMinecraftAssets(const QString& assets);
+ void applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets);
void applyTraits(const QSet<QString> &traits);
void applyTweakers(const QStringList &tweakers);
void applyJarMods(const QList<JarmodPtr> &jarMods);
void applyLibrary(LibraryPtr library);
void applyProblemSeverity(ProblemSeverity severity);
-public: /* getters for proifile variables */
+public: /* getters for profile variables */
QString getMinecraftVersion() const;
QString getMainClass() const;
QString getAppletClass() const;
QString getMinecraftVersionType() const;
- QString getMinecraftAssets() const;
+ MojangAssetIndexInfo::Ptr getMinecraftAssets() const;
QString getMinecraftArguments() const;
const QSet<QString> & getTraits() const;
const QStringList & getTweakers() const;
@@ -136,7 +137,7 @@ private: /* data */
QString m_minecraftVersionType;
/// Assets type - "legacy" or a version ID
- QString m_minecraftAssets;
+ MojangAssetIndexInfo::Ptr m_minecraftAssets;
/**
* arguments that should be used for launching minecraft
diff --git a/logic/minecraft/MojangVersionFormat.cpp b/logic/minecraft/MojangVersionFormat.cpp
index 779a2b7d..41723493 100644
--- a/logic/minecraft/MojangVersionFormat.cpp
+++ b/logic/minecraft/MojangVersionFormat.cpp
@@ -157,11 +157,15 @@ void MojangVersionFormat::readVersionProperties(const QJsonObject &in, VersionFi
}
Bits::readString(in, "type", out->type);
+ Bits::readString(in, "assets", out->assets);
if(in.contains("assetIndex"))
{
out->mojangAssetIndex = assetIndexFromJson(requireObject(in, "assetIndex"));
}
- Bits::readString(in, "assets", out->assets);
+ else if (!out->assets.isNull())
+ {
+ out->mojangAssetIndex = std::make_shared<MojangAssetIndexInfo>(out->assets);
+ }
out->m_releaseTime = timeFromS3Time(in.value("releaseTime").toString(""));
out->m_updateTime = timeFromS3Time(in.value("time").toString(""));
@@ -231,7 +235,6 @@ void MojangVersionFormat::writeVersionProperties(const VersionFile* in, QJsonObj
writeString(out, "mainClass", in->mainClass);
writeString(out, "minecraftArguments", in->minecraftArguments);
writeString(out, "type", in->type);
- writeString(out, "assets", in->assets);
if(!in->m_releaseTime.isNull())
{
writeString(out, "releaseTime", timeToS3Time(in->m_releaseTime));
@@ -244,6 +247,7 @@ void MojangVersionFormat::writeVersionProperties(const VersionFile* in, QJsonObj
{
out.insert("minimumLauncherVersion", in->minimumLauncherVersion);
}
+ writeString(out, "assets", in->assets);
if(in->mojangAssetIndex && in->mojangAssetIndex->known)
{
out.insert("assetIndex", assetIndexToJson(in->mojangAssetIndex));
diff --git a/logic/minecraft/VersionFile.cpp b/logic/minecraft/VersionFile.cpp
index 9cda717e..451c3c8b 100644
--- a/logic/minecraft/VersionFile.cpp
+++ b/logic/minecraft/VersionFile.cpp
@@ -40,7 +40,7 @@ void VersionFile::applyTo(MinecraftProfile *profile)
{
profile->applyMinecraftVersionType(type);
}
- profile->applyMinecraftAssets(assets);
+ profile->applyMinecraftAssets(mojangAssetIndex);
profile->applyTweakers(addTweakers);
profile->applyJarMods(jarMods);
diff --git a/logic/minecraft/onesix/OneSixInstance.cpp b/logic/minecraft/onesix/OneSixInstance.cpp
index f8b274ff..328c3b38 100644
--- a/logic/minecraft/onesix/OneSixInstance.cpp
+++ b/logic/minecraft/onesix/OneSixInstance.cpp
@@ -125,14 +125,15 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
QString absRootDir = QDir(minecraftRoot()).absolutePath();
token_mapping["game_directory"] = absRootDir;
QString absAssetsDir = QDir("assets/").absolutePath();
- token_mapping["game_assets"] = AssetsUtils::reconstructAssets(m_profile->getMinecraftAssets()).absolutePath();
+ auto assets = m_profile->getMinecraftAssets();
+ token_mapping["game_assets"] = AssetsUtils::reconstructAssets(assets->id).absolutePath();
token_mapping["user_properties"] = session->serializeUserProperties();
token_mapping["user_type"] = session->user_type;
// 1.7.3+ assets tokens
token_mapping["assets_root"] = absAssetsDir;
- token_mapping["assets_index_name"] = m_profile->getMinecraftAssets();
+ token_mapping["assets_index_name"] = assets->id;
QStringList parts = args_pattern.split(' ', QString::SkipEmptyParts);
for (int i = 0; i < parts.length(); i++)
diff --git a/logic/minecraft/onesix/OneSixUpdate.cpp b/logic/minecraft/onesix/OneSixUpdate.cpp
index fe1d3a6e..10d1e294 100644
--- a/logic/minecraft/onesix/OneSixUpdate.cpp
+++ b/logic/minecraft/onesix/OneSixUpdate.cpp
@@ -88,9 +88,9 @@ void OneSixUpdate::assetIndexStart()
setStatus(tr("Updating assets index..."));
OneSixInstance *inst = (OneSixInstance *)m_inst;
auto profile = inst->getMinecraftProfile();
- QString assetName = profile->getMinecraftAssets();
- QUrl indexUrl = "http://" + URLConstants::AWS_DOWNLOAD_INDEXES + assetName + ".json";
- QString localPath = assetName + ".json";
+ auto assets = profile->getMinecraftAssets();
+ QUrl indexUrl = assets->url;
+ QString localPath = assets->id + ".json";
auto job = new NetJob(tr("Asset index for %1").arg(inst->name()));
auto metacache = ENV.metacache();
@@ -114,36 +114,23 @@ void OneSixUpdate::assetIndexFinished()
OneSixInstance *inst = (OneSixInstance *)m_inst;
auto profile = inst->getMinecraftProfile();
- QString assetName = profile->getMinecraftAssets();
+ auto assets = profile->getMinecraftAssets();
- QString asset_fname = "assets/indexes/" + assetName + ".json";
- if (!AssetsUtils::loadAssetsIndexJson(asset_fname, &index))
+ QString asset_fname = "assets/indexes/" + assets->id + ".json";
+ // FIXME: this looks like a job for a generic validator based on json schema?
+ if (!AssetsUtils::loadAssetsIndexJson(assets->id, asset_fname, &index))
{
auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("asset_indexes", assetName + ".json");
+ auto entry = metacache->resolveEntry("asset_indexes", assets->id + ".json");
metacache->evictEntry(entry);
emitFailed(tr("Failed to read the assets index!"));
}
- QList<Md5EtagDownloadPtr> dls;
- for (auto object : index.objects.values())
- {
- QString objectName = object.hash.left(2) + "/" + object.hash;
- QFileInfo objectFile("assets/objects/" + objectName);
- if ((!objectFile.isFile()) || (objectFile.size() != object.size))
- {
- auto objectDL = MD5EtagDownload::make(QUrl("http://" + URLConstants::RESOURCE_BASE + objectName), objectFile.filePath());
- objectDL->m_total_progress = object.size;
- dls.append(objectDL);
- }
- }
- if (dls.size())
+ auto job = index.getDownloadJob();
+ if(job)
{
setStatus(tr("Getting the assets files from Mojang..."));
- auto job = new NetJob(tr("Assets for %1").arg(inst->name()));
- for (auto dl : dls)
- job->addNetAction(dl);
- jarlibDownloadJob.reset(job);
+ jarlibDownloadJob = job;
connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(assetsFinished()));
connect(jarlibDownloadJob.get(), &NetJob::failed, this, &OneSixUpdate::assetsFailed);
connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));