using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using UnityEditor;
using UnityEngine;
namespace VRC.ExampleCentral.Editor
{
///
/// Stores the GUID and Hash for each Asset in an Example
///
[Serializable]
public class AssetInfo
{
public string GUID { get; private set; }
public string Hash { get; private set; }
///
/// Initializes a new instance of the class with the specified GUID and hash.
/// Used for deserialization, after the hash is computed.
///
/// The GUID of the asset.
/// The hash of the asset.
public AssetInfo(string guid, string hash)
{
GUID = guid;
Hash = hash;
}
///
/// Initializes a new instance of the class with the specified GUID.
/// The hash is computed based on the asset's content.
///
/// The GUID of the asset.
public AssetInfo(string guid)
{
GUID = guid;
Hash = ComputeAssetHash(guid);
}
///
/// Computes the hash of the asset based on its content.
///
/// The GUID of the asset.
/// The computed hash of the asset.
private string ComputeAssetHash(string guid)
{
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
string fullPath = Path.Combine(Application.dataPath, assetPath.Substring("Assets/".Length));
if (!File.Exists(fullPath))
return "File Not Found";
try
{
using FileStream stream = File.OpenRead(fullPath);
using SHA256 sha = SHA256.Create();
byte[] hashBytes = sha.ComputeHash(stream);
StringBuilder sb = new StringBuilder();
foreach (byte b in hashBytes)
sb.Append(b.ToString("X2"));
return sb.ToString();
}
catch (Exception ex)
{
Debug.LogError($"Error computing hash for {assetPath}: {ex.Message}");
return "Error";
}
}
///
/// Serializes the asset to a string, using a pipe character as a separator.
///
/// A string representation of the asset's guid and hash.
public string Serialize()
{
return $"{GUID}|{Hash}";
}
///
/// Deserializes the asset information from a string.
///
/// The serialized data string.
/// An instance of .
/// Thrown when the serialized data format is invalid.
public static AssetInfo Deserialize(string serializedData)
{
var parts = serializedData.Split('|');
if (parts.Length != 2)
throw new ArgumentException("Invalid serialized data format");
return new AssetInfo(parts[0], parts[1]);
}
}
}