/* Copyright 2013-2015 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 #include #include #include #include #include #include #include #include "AssetsUtils.h" #include namespace AssetsUtils { /* * 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)) { qCritical() << "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) { qCritical() << "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()) { qCritical() << "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) { // qDebug() << 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) { // qDebug() << 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; } QDir reconstructAssets(QString assetsId) { 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(), assetsId + ".json"); QFile indexFile(indexPath); QDir virtualRoot(PathCombine(virtualDir.path(), assetsId)); if (!indexFile.exists()) { qCritical() << "No assets index file" << indexPath << "; can't reconstruct assets"; return virtualRoot; } qDebug() << "reconstructAssets" << assetsDir.path() << indexDir.path() << objectDir.path() << virtualDir.path() << virtualRoot.path(); AssetsIndex index; bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(indexPath, &index); if (loadAssetsIndex && index.isVirtual) { qDebug() << "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 (!original.exists()) continue; if (!target.exists()) { QFileInfo info(target_path); QDir target_dir = info.dir(); // qDebug() << target_dir; if (!target_dir.exists()) QDir("").mkpath(target_dir.path()); bool couldCopy = original.copy(target_path); qDebug() << " Copying" << original_path << "to" << target_path << QString::number(couldCopy); // << original.errorString(); } } // TODO: Write last used time to virtualRoot/.lastused } return virtualRoot; } }