summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--logic/OneSixInstance.cpp65
-rw-r--r--logic/OneSixInstance.h2
-rw-r--r--logic/OneSixVersion.cpp16
-rw-r--r--logic/OneSixVersion.h2
-rw-r--r--logic/assets/AssetsIndex.cpp11
-rw-r--r--logic/assets/AssetsIndex.h5
-rw-r--r--logic/assets/AssetsUtils.cpp109
-rw-r--r--logic/assets/AssetsUtils.h3
8 files changed, 210 insertions, 3 deletions
diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp
index 08b63bf9..a6b439a1 100644
--- a/logic/OneSixInstance.cpp
+++ b/logic/OneSixInstance.cpp
@@ -26,6 +26,8 @@
#include <JlCompress.h>
#include "gui/dialogs/OneSixModEditDialog.h"
#include "logger/QsLog.h"
+#include "logic/assets/AssetsIndex.h"
+#include "logic/assets/AssetsUtils.h"
OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_obj,
QObject *parent)
@@ -66,6 +68,63 @@ QString replaceTokensIn(QString text, QMap<QString, QString> with)
return result;
}
+QDir OneSixInstance::reconstructAssets(std::shared_ptr<OneSixVersion> version)
+{
+ QDir assetsDir = QDir("assets/");
+ QDir indexDir = QDir(PathCombine(assetsDir.path(), "indexes"));
+ QDir objectDir = QDir(PathCombine(assetsDir.path(), "objects"));
+ QDir virtualDir = QDir(PathCombine(assetsDir.path(), "virtual"));
+
+ QString indexPath = PathCombine(indexDir.path(), version->assets + ".json");
+ QFile indexFile(indexPath);
+ QDir virtualRoot(PathCombine(virtualDir.path(), version->assets));
+
+ if(!indexFile.exists())
+ {
+ QLOG_ERROR() << "No assets index file" << indexPath << "; can't reconstruct assets";
+ return virtualRoot;
+ }
+
+ QLOG_DEBUG() << "reconstructAssets" << assetsDir.path() << indexDir.path() << objectDir.path() << virtualDir.path() << virtualRoot.path();
+
+ AssetsIndex index;
+ bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(indexPath, &index);
+
+ if(loadAssetsIndex)
+ {
+ if(index.isVirtual)
+ {
+ QLOG_INFO() << "Reconstructing virtual assets folder at" << virtualRoot.path();
+
+ for(QString map : index.objects->keys())
+ {
+ AssetObject asset_object = index.objects->value(map);
+ QString target_path = PathCombine(virtualRoot.path(), map);
+ QFile target(target_path);
+
+ QString tlk = asset_object.hash.left(2);
+
+ QString original_path = PathCombine(PathCombine(objectDir.path(), tlk), asset_object.hash);
+ QFile original(original_path);
+ if(!target.exists())
+ {
+ QFileInfo info(target_path);
+ QDir target_dir = info.dir();
+ //QLOG_DEBUG() << target_dir;
+ if(!target_dir.exists()) QDir("").mkpath(target_dir.path());
+
+ bool couldCopy = original.copy(target_path);
+ QLOG_DEBUG() << " Copying" << original_path << "to" << target_path << QString::number(couldCopy);// << original.errorString();
+ }
+ }
+
+ // TODO: Write last used time to virtualRoot/.lastused
+ }
+ }
+
+ return virtualRoot;
+}
+
QStringList OneSixInstance::processMinecraftArgs(MojangAccountPtr account)
{
I_D(OneSixInstance);
@@ -93,10 +152,14 @@ QStringList OneSixInstance::processMinecraftArgs(MojangAccountPtr account)
QString absRootDir = QDir(minecraftRoot()).absolutePath();
token_mapping["game_directory"] = absRootDir;
QString absAssetsDir = QDir("assets/").absolutePath();
- token_mapping["game_assets"] = absAssetsDir;
+ token_mapping["game_assets"] = reconstructAssets(d->version).absolutePath();
//TODO: this is something new and not even fully implemented in the vanilla launcher.
token_mapping["user_properties"] = "{ }";
+ // 1.7.3+ assets tokens
+ token_mapping["assets_root"] = absAssetsDir;
+ token_mapping["assets_index_name"] = version->assets;
+
QStringList parts = args_pattern.split(' ', QString::SkipEmptyParts);
for (int i = 0; i < parts.length(); i++)
{
diff --git a/logic/OneSixInstance.h b/logic/OneSixInstance.h
index 042c104b..cc98d822 100644
--- a/logic/OneSixInstance.h
+++ b/logic/OneSixInstance.h
@@ -16,6 +16,7 @@
#pragma once
#include <QStringList>
+#include <QDir>
#include "BaseInstance.h"
@@ -73,4 +74,5 @@ public:
private:
QStringList processMinecraftArgs(MojangAccountPtr account);
+ QDir reconstructAssets(std::shared_ptr<OneSixVersion> version);
};
diff --git a/logic/OneSixVersion.cpp b/logic/OneSixVersion.cpp
index cc5b1de1..e586402b 100644
--- a/logic/OneSixVersion.cpp
+++ b/logic/OneSixVersion.cpp
@@ -17,6 +17,8 @@
#include "logic/OneSixLibrary.h"
#include "logic/OneSixRule.h"
+#include "logger/QsLog.h"
+
std::shared_ptr<OneSixVersion> fromJsonV4(QJsonObject root,
std::shared_ptr<OneSixVersion> fullVersion)
{
@@ -60,6 +62,18 @@ std::shared_ptr<OneSixVersion> fromJsonV4(QJsonObject root,
fullVersion->releaseTime = root.value("releaseTime").toString();
fullVersion->time = root.value("time").toString();
+ auto assetsID = root.value("assets");
+ if (assetsID.isString())
+ {
+ fullVersion->assets = assetsID.toString();
+ }
+ else
+ {
+ fullVersion->assets = "legacy";
+ }
+
+ QLOG_DEBUG() << "Assets version:" << fullVersion->assets;
+
// Iterate through the list, if it's a list.
auto librariesValue = root.value("libraries");
if (!librariesValue.isArray())
@@ -151,7 +165,7 @@ std::shared_ptr<OneSixVersion> OneSixVersion::fromJson(QJsonObject root)
root.value("minimumLauncherVersion").toDouble();
// ADD MORE HERE :D
- if (launcher_ver > 0 && launcher_ver <= 11)
+ if (launcher_ver > 0 && launcher_ver <= 12)
return fromJsonV4(root, readVersion);
else
{
diff --git a/logic/OneSixVersion.h b/logic/OneSixVersion.h
index 5718dafe..036f3d53 100644
--- a/logic/OneSixVersion.h
+++ b/logic/OneSixVersion.h
@@ -56,6 +56,8 @@ public:
QString releaseTime;
/// Release type - "release" or "snapshot"
QString type;
+ /// Assets type - "legacy" or a version ID
+ QString assets;
/**
* DEPRECATED: Old versions of the new vanilla launcher used this
* ex: "username_session_version"
diff --git a/logic/assets/AssetsIndex.cpp b/logic/assets/AssetsIndex.cpp
index 5b401a77..509f1add 100644
--- a/logic/assets/AssetsIndex.cpp
+++ b/logic/assets/AssetsIndex.cpp
@@ -15,6 +15,17 @@
#include "AssetsIndex.h"
+AssetsIndex::AssetsIndex()
+{
+ // TODO: leak?
+ this->objects = new QMap<QString, AssetObject>();
+ this->isVirtual = false;
+}
+
AssetObject::AssetObject(QString hash, qint64 size) : hash(hash), size(size)
{
}
+
+AssetObject::AssetObject()
+{
+}
diff --git a/logic/assets/AssetsIndex.h b/logic/assets/AssetsIndex.h
index 019265f9..09ef0d92 100644
--- a/logic/assets/AssetsIndex.h
+++ b/logic/assets/AssetsIndex.h
@@ -23,14 +23,17 @@ class AssetObject;
class AssetsIndex
{
public:
- QMap<QString, AssetObject> objects;
+ QMap<QString, AssetObject> *objects;
bool isVirtual;
+
+ AssetsIndex();
};
class AssetObject
{
public:
AssetObject(QString hash, qint64 size);
+ AssetObject();
bool equals(AssetObject* other);
QString getHashCode();
diff --git a/logic/assets/AssetsUtils.cpp b/logic/assets/AssetsUtils.cpp
index 3589161a..8d7d6f46 100644
--- a/logic/assets/AssetsUtils.cpp
+++ b/logic/assets/AssetsUtils.cpp
@@ -16,6 +16,9 @@
#include <QDir>
#include <QDirIterator>
#include <QCryptographicHash>
+#include <QJsonParseError>
+#include <QJsonDocument>
+#include <QJsonObject>
#include "AssetsUtils.h"
#include "MultiMC.h"
@@ -112,4 +115,110 @@ void migrateOldAssets()
}
}
}
+
+/*
+ * Returns true on success, with index populated
+ * index is undefined otherwise
+ */
+bool loadAssetsIndexJson(QString path, AssetsIndex *index)
+{
+/*
+{
+ "objects": {
+ "icons/icon_16x16.png": {
+ "hash": "bdf48ef6b5d0d23bbb02e17d04865216179f510a",
+ "size": 3665
+ },
+ ...
+ }
+ }
+}
+*/
+
+ QFile file(path);
+
+ // Try to open the file and fail if we can't.
+ // TODO: We should probably report this error to the user.
+ if (!file.open(QIODevice::ReadOnly))
+ {
+ QLOG_ERROR() << "Failed to read assets index file" << path;
+ return false;
+ }
+
+ // Read the file and close it.
+ QByteArray jsonData = file.readAll();
+ file.close();
+
+ QJsonParseError parseError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError);
+
+ // Fail if the JSON is invalid.
+ if (parseError.error != QJsonParseError::NoError)
+ {
+ QLOG_ERROR() << "Failed to parse assets index file:" << parseError.errorString() << "at offset " << QString::number(parseError.offset);
+ return false;
+ }
+
+ // Make sure the root is an object.
+ if (!jsonDoc.isObject())
+ {
+ QLOG_ERROR() << "Invalid assets index JSON: Root should be an array.";
+ return false;
+ }
+
+ QJsonObject root = jsonDoc.object();
+
+ QJsonValue isVirtual = root.value("virtual");
+ if(!isVirtual.isUndefined())
+ {
+ index->isVirtual = isVirtual.toBool(false);
+ }
+
+ QJsonValue objects = root.value("objects");
+ QVariantMap map = objects.toVariant().toMap();
+
+ for(QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter) {
+ //QLOG_DEBUG() << iter.key();
+
+ QVariant variant = iter.value();
+ QVariantMap nested_objects = variant.toMap();
+
+ AssetObject object;
+
+ for(QVariantMap::const_iterator nested_iter = nested_objects.begin(); nested_iter != nested_objects.end(); ++nested_iter) {
+ //QLOG_DEBUG() << nested_iter.key() << nested_iter.value().toString();
+ QString key = nested_iter.key();
+ QVariant value = nested_iter.value();
+
+ if(key == "hash")
+ {
+ object.hash = value.toString();
+ }
+ else if(key == "size")
+ {
+ object.size = value.toDouble();
+ }
+ }
+
+ index->objects->insert(iter.key(), object);
+ }
+
+ return true;
+ /*for (QJsonValue accountVal : objects)
+ {
+ QJsonObject accountObj = accountVal.toObject();
+ MojangAccountPtr account = MojangAccount::loadFromJson(accountObj);
+ if (account.get() != nullptr)
+ {
+ connect(account.get(), SIGNAL(changed()), SLOT(accountChanged()));
+ m_accounts.append(account);
+ }
+ else
+ {
+ QLOG_WARN() << "Failed to load an account.";
+ }
+ }*/
+
+ //return false;
+}
}
diff --git a/logic/assets/AssetsUtils.h b/logic/assets/AssetsUtils.h
index 80b0d676..88a3b0dc 100644
--- a/logic/assets/AssetsUtils.h
+++ b/logic/assets/AssetsUtils.h
@@ -15,7 +15,10 @@
#pragma once
+#include "AssetsIndex.h"
+
namespace AssetsUtils
{
void migrateOldAssets();
+bool loadAssetsIndexJson(QString file, AssetsIndex* index);
}