//============= Copyright (c) Ludic GmbH, All rights reserved. ============== // // Purpose: Part of the My Behaviour Tree Code // //============================================================================= using System.Collections; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using UnityEngine; namespace MyBT { [System.Serializable] public class FileHash { [SerializeField] private List<string> hashCache; public bool debugLog = false; public void UpdateHashCache (FileHash compareFileHash) { hashCache = compareFileHash.GetCurrentHashCache(); } public void UpdateHashCache (List<string> newHashCache) { if (debugLog) Debug.Log("UpdateHashCache"); hashCache = newHashCache; } public void UpdateHashCacheFromTextAsset (List<UnityEngine.TextAsset> textAssets) { UpdateHashCache(TextAssetHash(textAssets)); // Debug.LogError("FileHash.UpdateHashCacheFromTextAsset: " + this); } public void ClearHashCache () { if (debugLog) Debug.Log("ClearHashCache"); hashCache = null; } public List<string> GetCurrentHashCache () { return hashCache; } public bool HashChanged (FileHash compareFileHash, bool allowNull = true) { bool changed = HashChanged(compareFileHash.GetCurrentHashCache(), allowNull); if (debugLog) Debug.Log("CheckGenerationOutdated:\tThis Hash:\t" + this + " \n"+ "\t\t\tCompared Hash:\t" + compareFileHash); return changed; } // public bool HashChangedAndNotNull (FileHash compareFileHash) { // bool changed = HashChanged(compareFileHash.GetCurrentHashCache(), false); // if (debugLog) Debug.Log("CheckGenerationOutdated:\tThis Hash:\t" + this + " \n"+ // "\t\t\tCompared Hash:\t" + compareFileHash); // return changed; // } public bool HashChanged (List<string> compareHashes, bool allowNull = true) { if (!allowNull && ((compareHashes == null) || (hashCache == null))) { return true; } if (compareHashes == hashCache) { return false; } if ((compareHashes != null) && (hashCache != null) && (compareHashes.Count == hashCache.Count)) { bool anyChanged = false; for (int i=0; i<compareHashes.Count; i++) { if ((i < compareHashes.Count) && (i < hashCache.Count)) { bool differ = (compareHashes[i] != hashCache[i]); // if (debugLog) Debug.Log("BtFileHashChanged: bt script "+i+" changed "+differ); anyChanged |= differ; } } if (debugLog) Debug.Log("BtFileHashChanged: some hash differ: " + this + " " + ((compareHashes!=null)?string.Join(", ", compareHashes.Select(g=>g)):"null")); return anyChanged; } else { if (debugLog) Debug.Log("BtFileHashChanged: hash length changed, or null: compareHashes=" + (compareHashes!=null?compareHashes.Count.ToString():"null") + " btFileHashCache=" + (hashCache!=null?hashCache.Count.ToString():"null")); } return true; } public bool HashChangedFromTextAsset (List<UnityEngine.TextAsset> textAssets) { return HashChanged(TextAssetHash(textAssets)); } /// <summary> /// return list of hashes generated from textassets /// </summary> public List<string> TextAssetHash (List<UnityEngine.TextAsset> textAssets) { List<string> fileHashes = new List<string>(); //[taskScripts.Count]; for (int i=0; i<textAssets.Count; i++) { TextAsset txt = textAssets[i]; if (txt!= null) { fileHashes.Add(GetHash(txt.text)); } else { fileHashes.Add(null); } // Resources.UnloadAsset(txt); } if (debugLog) Debug.Log("TextAssetHash: generated hashes "+string.Join(", ", fileHashes.Select(f=>f))); return fileHashes; } /// <summary> /// create a hash from a string /// </summary> private string GetHash(string usedString) { MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); //byte[] bytes = Encoding.ASCII.GetBytes(usedString+secretKey); // this wrong because can't receive korean character byte[] bytes = Encoding.UTF8.GetBytes(usedString); // + secretKey byte[] hash = md5.ComputeHash(bytes); StringBuilder sb = new StringBuilder(); for (int i = 0; i < hash.Length; i++) { sb.Append(hash[i].ToString("x2")); } return sb.ToString(); } public override string ToString() { return ((hashCache!=null)?string.Join(", ", hashCache.Select(g=>g)):"null"); } } }