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}