AddVuforiaEnginePackage.cs
6.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
using System;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public class AddVuforiaEnginePackage
{
const string VUFORIA_VERSION = "9.1.7";
const string PACKAGE_KEY = "\"com.ptc.vuforia.engine\"";
static readonly string sPackagesPath = Path.Combine(Application.dataPath, "..", "Packages");
static readonly string sManifestJsonPath = Path.Combine(sPackagesPath, "manifest.json");
static readonly ScopedRegistry sVuforiaRegistry = new ScopedRegistry()
{
name = "Vuforia",
url = "https://registry.packages.developer.vuforia.com/",
scopes = new[] { "com.ptc.vuforia" }
};
static AddVuforiaEnginePackage()
{
if (Application.isBatchMode)
return;
var manifest = Manifest.JsonDeserialize(sManifestJsonPath);
var registries = manifest.ScopedRegistries.ToList();
if (registries.Any(r => r == sVuforiaRegistry))
return;
if (EditorUtility.DisplayDialog("Add Vuforia Engine Package",
"Would you like to update your project to always be able to find the latest version of the Vuforia Engine in the package manager window?\n" +
$"If a Vuforia Engine package is already present in your project it will be upgraded to version {VUFORIA_VERSION}", "Update", "Cancel"))
{
UpdateManifest(manifest);
}
}
static void UpdateManifest(Manifest manifest)
{
AddRegistry(manifest, sVuforiaRegistry);
SetVuforiaVersion(manifest);
manifest.JsonSerialize(sManifestJsonPath);
AssetDatabase.Refresh();
}
static void SetVuforiaVersion(Manifest manifest)
{
var dependencies = manifest.Dependencies.Split(',').ToList();
var versionSet = false;
for(var i = 0; i < dependencies.Count; i++)
{
if(!dependencies[i].Contains(PACKAGE_KEY))
continue;
var kvp = dependencies[i].Split(':');
kvp[1] = $"\"{VUFORIA_VERSION}\""; //version string of the package
dependencies[i] = string.Join(":", kvp);
versionSet = true;
}
if (!versionSet)
dependencies.Insert(0, $"\n {PACKAGE_KEY}: \"{VUFORIA_VERSION}\"");
manifest.Dependencies = string.Join(",", dependencies);
}
static void AddRegistry(Manifest manifest, ScopedRegistry scopedRegistry)
{
var registries = manifest.ScopedRegistries.ToList();
if (registries.Any(r => r == scopedRegistry))
return;
registries.Add(scopedRegistry);
manifest.ScopedRegistries = registries.ToArray();
}
class Manifest
{
const int INDEX_NOT_FOUND = -1;
const string DEPENDENCIES_KEY = "\"dependencies\"";
public ScopedRegistry[] ScopedRegistries;
public string Dependencies;
public void JsonSerialize(string path)
{
var jsonString = JsonUtility.ToJson(
new UnitySerializableManifest {scopedRegistries = ScopedRegistries, dependencies = new DependencyPlaceholder()},
true);
var startIndex = GetDependenciesStart(jsonString);
var endIndex = GetDependenciesEnd(jsonString, startIndex);
var stringBuilder = new StringBuilder();
stringBuilder.Append(jsonString.Substring(0, startIndex));
stringBuilder.Append(Dependencies);
stringBuilder.Append(jsonString.Substring(endIndex, jsonString.Length - endIndex));
File.WriteAllText(path, stringBuilder.ToString());
}
public static Manifest JsonDeserialize(string path)
{
var jsonString = File.ReadAllText(path);
var registries = JsonUtility.FromJson<UnitySerializableManifest>(jsonString).scopedRegistries ?? new ScopedRegistry[0];
var dependencies = DeserializeDependencies(jsonString);
return new Manifest { ScopedRegistries = registries, Dependencies = dependencies };
}
static string DeserializeDependencies(string json)
{
var startIndex = GetDependenciesStart(json);
var endIndex = GetDependenciesEnd(json, startIndex);
if (startIndex == INDEX_NOT_FOUND || endIndex == INDEX_NOT_FOUND)
return null;
var dependencies = json.Substring(startIndex, endIndex - startIndex);
return dependencies;
}
static int GetDependenciesStart(string json)
{
var dependenciesIndex = json.IndexOf(DEPENDENCIES_KEY, StringComparison.InvariantCulture);
if (dependenciesIndex == INDEX_NOT_FOUND)
return INDEX_NOT_FOUND;
var dependenciesStartIndex = json.IndexOf('{', dependenciesIndex + DEPENDENCIES_KEY.Length);
if (dependenciesStartIndex == INDEX_NOT_FOUND)
return INDEX_NOT_FOUND;
dependenciesStartIndex++; //add length of '{' to starting point
return dependenciesStartIndex;
}
static int GetDependenciesEnd(string jsonString, int dependenciesStartIndex)
{
return jsonString.IndexOf('}', dependenciesStartIndex);
}
}
class UnitySerializableManifest
{
public ScopedRegistry[] scopedRegistries;
public DependencyPlaceholder dependencies;
}
[Serializable]
struct ScopedRegistry
{
public string name;
public string url;
public string[] scopes;
public override bool Equals(object obj)
{
if (!(obj is ScopedRegistry))
return false;
var other = (ScopedRegistry) obj;
return name == other.name &&
url == other.url &&
scopes.SequenceEqual(other.scopes);
}
public static bool operator ==(ScopedRegistry a, ScopedRegistry b)
{
return a.Equals(b);
}
public static bool operator !=(ScopedRegistry a, ScopedRegistry b)
{
return !a.Equals(b);
}
public override int GetHashCode()
{
var hash = 17;
foreach (var scope in scopes)
hash = hash * 23 + (scope == null ? 0 : scope.GetHashCode());
hash = hash * 23 + (name == null ? 0 : name.GetHashCode());
hash = hash * 23 + (url == null ? 0 : url.GetHashCode());
return hash;
}
}
[Serializable]
struct DependencyPlaceholder { }
}