Files
DeviantMobile-Rohan/Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/AssetPacks/AssetBundleFolder.cs

185 lines
7.0 KiB
C#

// Copyright 2019 Google LLC
//
// 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
//
// https://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.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
namespace Google.Android.AppBundle.Editor.Internal.AssetPacks
{
/// <summary>
/// Internal-only representation of a folder containing AssetBundles.
/// </summary>
public class AssetBundleFolder
{
/// <summary>
/// The error state of this folder or <see cref="AssetPackFolderState.Ok"/>.
/// </summary>
public AssetPackFolderState State { get; private set; }
/// <summary>
/// The path represented by the folder.
/// </summary>
public string FolderPath { get; private set; }
/// <summary>
/// The texture compression format of AssetBundles inside this folder, based on the folder name.
/// </summary>
public TextureCompressionFormat TextureCompressionFormat { get; private set; }
/// <summary>
/// The number of AssetBundles found in this folder.
/// Note: this value is cached during calls to <see cref="ExtractAssetBundleVariant"/>.
/// </summary>
public int AssetBundleCount { get; private set; }
private string _searchedManifestFileName;
/// <summary>
/// Create a new AssetBundleFolder for a given path (which is then immutable).
/// Call <see cref="Refresh"/> to update the folder state and texture compression format targeting.
/// </summary>
public AssetBundleFolder(string folderPath)
{
AssetBundleCount = 0;
FolderPath = folderPath;
}
/// <summary>
/// Update the folder state and texture compression format targeting, if any.
/// </summary>
/// <returns>true if the refresh was properly done (no errors)</returns>
public bool Refresh()
{
var directoryInfo = new DirectoryInfo(FolderPath);
if (!directoryInfo.Exists)
{
AssetBundleCount = 0;
State = AssetPackFolderState.FolderMissing;
return false;
}
var files = directoryInfo.GetFiles();
if (files.Length == 0)
{
AssetBundleCount = 0;
State = AssetPackFolderState.FolderEmpty;
return false;
}
TextureCompressionFormat textureCompressionFormat;
TextureTargetingTools.GetTextureCompressionFormatAndStripSuffix(
directoryInfo.Name,
out textureCompressionFormat,
out _searchedManifestFileName);
TextureCompressionFormat = textureCompressionFormat;
return true;
}
/// <summary>
/// Scans and returns every <see cref="AssetBundleVariant"/> found in this folder.
/// </summary>
public IDictionary<string, AssetBundleVariant> ExtractAssetBundleVariant()
{
AssetBundleCount = 0;
var assetBundleVariants = new Dictionary<string, AssetBundleVariant>();
if (!Refresh())
{
return assetBundleVariants;
}
var directoryInfo = new DirectoryInfo(FolderPath);
var files = directoryInfo.GetFiles();
var fileDictionary = files.ToDictionary(file => file.Name, file => file);
// Look for an AssetBundle file with the same name as the directory that contains it.
// This AssetBundle file contains a single asset, which is of type AssetBundleManifest.
// See https://unity3d.com/learn/tutorials/topics/best-practices/assetbundle-fundamentals
FileInfo manifestFileInfo;
if (!fileDictionary.TryGetValue(_searchedManifestFileName, out manifestFileInfo))
{
State = AssetPackFolderState.ManifestFileMissing;
return assetBundleVariants;
}
var manifestFilePath = manifestFileInfo.FullName;
AssetBundle manifestAssetBundle;
try
{
manifestAssetBundle = AssetBundle.LoadFromFile(manifestFilePath);
}
catch (Exception ex)
{
Debug.LogErrorFormat("Exception loading AssetBundle file containing manifest ({0}): {1}",
manifestFilePath, ex);
State = AssetPackFolderState.ManifestFileLoadError;
return assetBundleVariants;
}
try
{
var manifest = manifestAssetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
if (manifest == null)
{
State = AssetPackFolderState.ManifestAssetMissing;
return assetBundleVariants;
}
var allAssetBundles = manifest.GetAllAssetBundles();
if (allAssetBundles.Length == 0)
{
State = AssetPackFolderState.AssetBundlesMissing;
return assetBundleVariants;
}
foreach (var assetBundleName in allAssetBundles)
{
FileInfo assetBundleFileInfo;
var fileSizeBytes = fileDictionary.TryGetValue(assetBundleName, out assetBundleFileInfo)
? assetBundleFileInfo.Length
: AssetBundleVariant.FileSizeIfMissing;
assetBundleVariants.Add(
assetBundleName,
AssetBundleVariant.CreateVariant(
assetBundleName,
fileSizeBytes,
manifest.GetDirectDependencies(assetBundleName),
manifest.GetAllDependencies(assetBundleName),
Path.Combine(FolderPath, assetBundleName)));
}
AssetBundleCount = assetBundleVariants.Count;
return assetBundleVariants;
}
catch (Exception ex)
{
Debug.LogErrorFormat(
"Exception loading AssetBundleManifest from AssetBundle ({0}): {1}", manifestFilePath, ex);
State = AssetPackFolderState.ManifestAssetLoadError;
return assetBundleVariants;
}
finally
{
// If an AssetBundle isn't unloaded, the Editor will have to be restarted to load it again.
manifestAssetBundle.Unload(true);
}
}
}
}