A game about forced loneliness, made by TACStudios
1using System; 2using System.Linq; 3using System.Security.Cryptography; 4using System.Text; 5using UnityEngine; 6 7namespace UnityEditor.ShaderGraph.Serialization 8{ 9 [Serializable] 10 public class JsonObject : ISerializationCallbackReceiver 11 { 12 public virtual int latestVersion { get; } = 0; 13 14 [SerializeField] 15 protected int m_SGVersion = 0; 16 public virtual int sgVersion { get => m_SGVersion; protected set => m_SGVersion = value; } 17 18 internal protected delegate void VersionChange(int newVersion); 19 internal protected VersionChange onBeforeVersionChange; 20 internal protected Action onAfterVersionChange; 21 22 internal void ChangeVersion(int newVersion) 23 { 24 if (newVersion == sgVersion) 25 { 26 return; 27 } 28 if (newVersion < 0) 29 { 30 Debug.LogError("Cant downgrade past version 0"); 31 return; 32 } 33 if (newVersion > latestVersion) 34 { 35 Debug.LogError("Cant upgrade to a version >= the current latest version"); 36 return; 37 } 38 39 onBeforeVersionChange?.Invoke(newVersion); 40 sgVersion = newVersion; 41 onAfterVersionChange?.Invoke(); 42 } 43 44 public JsonObject() 45 { 46 sgVersion = latestVersion; 47 } 48 49 public static readonly string emptyObjectId = Guid.Empty.ToString("N"); 50 51 [SerializeField] 52 string m_Type; 53 54 [SerializeField] 55 string m_ObjectId = Guid.NewGuid().ToString("N"); 56 57 internal void OverrideObjectId(string namespaceUid, string newObjectId) { m_ObjectId = GenerateNamespaceUUID(namespaceUid, newObjectId).ToString("N"); } 58 internal void OverrideObjectId(string newObjectId) { m_ObjectId = newObjectId; } 59 60 public string objectId => m_ObjectId; 61 62 public bool objectIdIsEmpty => m_ObjectId.Equals(emptyObjectId); 63 void ISerializationCallbackReceiver.OnBeforeSerialize() 64 { 65 m_Type = $"{GetType().FullName}"; 66 OnBeforeSerialize(); 67 } 68 69 public virtual T CastTo<T>() where T : JsonObject { return (T)this; } 70 public virtual string Serialize() { return EditorJsonUtility.ToJson(this, true); } 71 public virtual void Deserailize(string typeInfo, string jsonData) { EditorJsonUtility.FromJsonOverwrite(jsonData, this); } 72 73 public virtual void OnBeforeSerialize() { } 74 75 public virtual void OnBeforeDeserialize() { } 76 77 public virtual void OnAfterDeserialize() { } 78 79 public virtual void OnAfterDeserialize(string json) { } 80 81 public virtual void OnAfterMultiDeserialize(string json) { } 82 83 internal static Guid GenerateNamespaceUUID(string Namespace, string Name) 84 { 85 Guid namespaceGuid; 86 if (!Guid.TryParse(Namespace, out namespaceGuid)) 87 { 88 // Fallback namespace in case the one provided is invalid. 89 // If an object ID was used as the namespace, this shouldn't normally be reachable. 90 namespaceGuid = new Guid("6ba7b812-9dad-11d1-80b4-00c04fd430c8"); 91 } 92 return GenerateNamespaceUUID(namespaceGuid, Name); 93 } 94 95 internal static Guid GenerateNamespaceUUID(Guid Namespace, string Name) 96 { 97 // Generate a deterministic guid using namespace guids: RFC 4122 §4.3 version 5. 98 void FlipByNetworkOrder(byte[] bytes) 99 { bytes = new byte[] { bytes[3], bytes[2], bytes[1], bytes[0], bytes[5], bytes[4], bytes[7], bytes[6] }; } 100 101 var namespaceBytes = Namespace.ToByteArray(); 102 FlipByNetworkOrder(namespaceBytes); 103 var nameBytes = Encoding.UTF8.GetBytes(Name); 104 var hash = SHA1.Create().ComputeHash(namespaceBytes.Concat(nameBytes).ToArray()); 105 byte[] newguid = new byte[16]; 106 Array.Copy(hash, newguid, 16); 107 newguid[6] = (byte)((newguid[6] & 0x0F) | 0x80); 108 newguid[8] = (byte)((newguid[8] & 0x3F) | 0x80); 109 FlipByNetworkOrder(newguid); 110 return new Guid(newguid); 111 } 112 } 113}