public MethodMeta(ISharedTable stringTable, TypeMeta declaringType, BinaryReader reader) { byte[] rawData = reader.ReadBytes(12); this.name = stringTable.FetchString(rawData[0] | (rawData[1] << 8) | (rawData[2] << 16)); this.declaringType = stringTable.FetchString(rawData[3] | (rawData[4] << 8) | (rawData[5] << 16)); this.returnType = stringTable.FetchString(rawData[6] | (rawData[7] << 8) | (rawData[8] << 16)); byte flags = rawData[9]; this.isPublic = (flags & 1) != 0; int length = rawData[10] | (rawData[11] << 8); this.parametersType = new string[length]; this.parametersName = new string[length]; rawData = reader.ReadBytes(length * 6); for (int i = 0, j = 0; j < length; ++j, i += 6) { this.parametersType[j] = stringTable.FetchString(rawData[i] | (rawData[i + 1] << 8) | (rawData[i + 2] << 16)); this.parametersName[j] = stringTable.FetchString(rawData[i + 3] | (rawData[i + 4] << 8) | (rawData[i + 5] << 16)); } if ((flags & 4) != 0) { this.errorMessage = stringTable.FetchString(reader.ReadInt24()); } }
public AssemblyMeta(ISharedTable sharedStringTable, BinaryReader reader) { this.assemblyPath = reader.ReadString(); this.friendAssemblies = new string[reader.ReadUInt16()]; byte[] rawData = reader.ReadBytes(this.friendAssemblies.Length * 3); for (int i = 0, j = 0, max = this.friendAssemblies.Length; i < max; ++i, j += 3) { this.friendAssemblies[i] = sharedStringTable.FetchString(rawData[j] | (rawData[j + 1] << 8) | (rawData[j + 2] << 16)); } this.types = new TypeMeta[reader.ReadInt32()]; rawData = reader.ReadBytes(this.types.Length * 3); for (int i = 0, j = 0, max = this.types.Length; i < max; ++i, j += 3) { try { TypeMeta typeMeta = sharedStringTable.FetchType(rawData[j] | (rawData[j + 1] << 8) | (rawData[j + 2] << 16)); this.types[i] = typeMeta; this.typeCache.Add(typeMeta.FullName, typeMeta); } catch (Exception) { Debug.LogError("Type #" + i + " failed in assembly \"" + this.assemblyPath + "\"."); throw; } } }
public FieldMeta(ISharedTable stringTable, TypeMeta declaringType, BinaryReader reader) { byte[] rawData = reader.ReadBytes(12); this.name = stringTable.FetchString(rawData[0] | (rawData[1] << 8) | (rawData[2] << 16)); this.errorMessage = stringTable.FetchString(rawData[3] | (rawData[4] << 8) | (rawData[5] << 16)); this.declaringType = stringTable.FetchString(rawData[6] | (rawData[7] << 8) | (rawData[8] << 16)); this.type = stringTable.FetchString(rawData[9] | (rawData[10] << 8) | (rawData[11] << 16)); }
public MethodMeta Resolve(MethodReference methodRef) { TypeMeta type = this.Resolve(methodRef.DeclaringType); if (type != null) { return(type.Resolve(methodRef)); } return(null); }
public PropertyMeta Resolve(PropertyReference propertyRef) { TypeMeta type = this.Resolve(propertyRef.DeclaringType); if (type != null) { return(type.Resolve(propertyRef)); } return(null); }
public FieldMeta Resolve(FieldReference fieldRef) { TypeMeta type = this.Resolve(fieldRef.DeclaringType); if (type != null) { return(type.Resolve(fieldRef)); } return(null); }
public EventMeta Resolve(EventReference eventRef) { TypeMeta type = this.Resolve(eventRef.DeclaringType); if (type != null) { return(type.Resolve(eventRef)); } return(null); }
public EventMeta(ISharedTable stringTable, TypeMeta declaringType, BinaryReader reader) { byte[] rawData = reader.ReadBytes(10); this.name = stringTable.FetchString(rawData[0] | (rawData[1] << 8) | (rawData[2] << 16)); this.declaringType = stringTable.FetchString(rawData[3] | (rawData[4] << 8) | (rawData[5] << 16)); this.type = stringTable.FetchString(rawData[6] | (rawData[7] << 8) | (rawData[8] << 16)); byte flags = rawData[9]; this.hasAdd = (flags & 1) != 0; this.hasRemove = (flags & 2) != 0; if ((flags & 4) != 0) { this.errorMessage = stringTable.FetchString(reader.ReadInt24()); } }
public TypeMeta Resolve(AssemblyMeta assemblyMeta, TypeReference typeRef) { if (typeRef.Namespace.EndsWith(this.Name) == false) { throw new Exception("Mismatch namespace \"" + typeRef.Namespace + "\"."); } for (int i = 0, max = this.Types.Count; i < max; ++i) { TypeMeta type = this.Types[i]; if (type.Name == typeRef.Name) { if (type.IsPublic == true || assemblyMeta.IsFriend(typeRef.Module.Assembly.Name.Name) == true) { return(type); } break; } } return(null); }
public void ResolveReferences(ICollection <TypeReference> types, ICollection <FieldReference> fields, ICollection <MethodReference> methods) { int assembliesMetaLength = this.unityMeta.AssembliesMeta.Length; DynamicOrderedArray <AssemblyMeta> assemblies = new DynamicOrderedArray <AssemblyMeta>(this.unityMeta.AssembliesMeta); foreach (TypeReference typeRef in types) { TypeMeta meta = null; int j = 0; for (; j < assembliesMetaLength && meta == null; ++j) { meta = assemblies.array[j].Resolve(typeRef); } if (meta != null) { assemblies.BringToTop(j - 1); if (meta.ErrorMessage != null) { this.foundTypes.Add(meta); } } else { // Type not found, maybe look into other types. Might be renamed. TypeMeta lastFound = null; string typeRefNamespace = typeRef.Namespace; string typeRefName = typeRef.Name; j = 0; for (; j < assembliesMetaLength && lastFound == null; ++j) { for (int k = 0, max = assemblies.array[j].Types.Length; k < max; ++k) { TypeMeta typeMeta = assemblies.array[j].Types[k]; if (typeMeta.Name == typeRefName) { if (lastFound == null || this.GetLevenshteinDistance(lastFound.Namespace, typeRefNamespace) > this.GetLevenshteinDistance(typeMeta.Namespace, typeRefNamespace)) { lastFound = typeMeta; break; } } } } if (lastFound != null) { this.missingTypes.Add(new TypeMeta(typeRef, "Type not found, but a similar Type has been found at \"" + lastFound.FullName + "\".")); } else { this.missingTypes.Add(new TypeMeta(typeRef)); } } } foreach (FieldReference fieldRef in fields) { FieldMeta meta = null; int j = 0; for (; j < assembliesMetaLength && meta == null; ++j) { meta = assemblies.array[j].Resolve(fieldRef); } if (meta != null) { assemblies.BringToTop(j - 1); if (meta.ErrorMessage != null) { this.foundFields.Add(meta); } } else { this.missingFields.Add(new FieldMeta(fieldRef)); } } foreach (MethodReference methodRef in methods) { MethodMeta meta = null; int j = 0; for (; j < assembliesMetaLength && meta == null; ++j) { meta = assemblies.array[j].Resolve(methodRef); } if (meta != null) { assemblies.BringToTop(j - 1); if (meta.ErrorMessage != null) { this.foundMethods.Add(meta); } } else { this.missingMethods.Add(new MethodMeta(methodRef)); } } }
protected virtual void OnGUI() { EditorGUILayout.HelpBox("Meta assemblies are libraries (or DLL) converted, compacted & saved to be reused offline.\nAllowing to verify compatibility with a Unity version without installing it.", MessageType.Info); if (this.metaLabel == null || this.metaLabel.Length != this.meta.Length) { this.metaLabel = new string[this.meta.Length]; for (int i = 0, max = this.metaLabel.Length; i < max; ++i) { this.metaLabel[i] = (i + 1) + " - " + Path.GetFileNameWithoutExtension(this.meta[i].AssemblyPath); } } using (LabelWidthRestorer.Get(100F)) { EditorGUI.BeginChangeCheck(); this.selectedMeta = EditorGUILayout.Popup("Meta Assembly", this.selectedMeta, this.metaLabel); if (EditorGUI.EndChangeCheck() == true) { this.typesLabel = null; } } if (this.selectedMeta >= 0 && this.selectedMeta < this.meta.Length) { using (var scroll = new EditorGUILayout.ScrollViewScope(this.scrollPosition)) { this.scrollPosition = scroll.scrollPosition; AssemblyMeta assemblyMeta = this.meta[this.selectedMeta]; using (LabelWidthRestorer.Get(60F)) { EditorGUILayout.LabelField("Location", assemblyMeta.AssemblyPath); using (new EditorGUILayout.HorizontalScope(EditorStyles.toolbar)) { this.displayFriends = EditorGUILayout.Foldout(this.displayFriends, "Friends (" + assemblyMeta.FriendAssemblies.Length + " assemblies)", true); } } if (this.displayFriends == true) { ++EditorGUI.indentLevel; for (int i = 0, max = assemblyMeta.FriendAssemblies.Length; i < max; ++i) { EditorGUILayout.LabelField(assemblyMeta.FriendAssemblies[i]); } --EditorGUI.indentLevel; } GUILayout.Space(10F); using (new EditorGUILayout.HorizontalScope(EditorStyles.toolbar)) { EditorGUILayout.LabelField(this.displayNamespaces == true ? "Namespaces" : "Types (" + assemblyMeta.Types.Length + ")"); GUILayout.FlexibleSpace(); if (GUILayout.Button(this.displayNamespaces == true ? "Display Type" : "Display Namespace", EditorStyles.toolbarButton) == true) { this.displayNamespaces = !this.displayNamespaces; } } if (this.displayNamespaces == true) { for (int i = 0, max = assemblyMeta.GlobalNamespace.Namespaces.Count; i < max; ++i) { this.DrawNamespace(assemblyMeta.GlobalNamespace.Namespaces[i]); } } else { if (this.typesLabel == null || this.typesLabel.Length != assemblyMeta.Types.Length) { this.typesLabel = new string[assemblyMeta.Types.Length]; StringBuilder buffer = Utility.GetBuffer(); for (int i = 0, max = assemblyMeta.Types.Length; i < max; ++i) { TypeMeta typeMeta = assemblyMeta.Types[i]; buffer.Length = 0; buffer.Append(typeMeta.FullName); //buffer.Append(" ("); if (typeMeta.Events.Length > 0) { buffer.Append(" - "); buffer.Append(typeMeta.Events.Length); buffer.Append(" events"); } if (typeMeta.Fields.Length > 0) { buffer.Append(" - "); buffer.Append(typeMeta.Fields.Length); buffer.Append(" fields"); } if (typeMeta.Properties.Length > 0) { buffer.Append(" - "); buffer.Append(typeMeta.Properties.Length); buffer.Append(" properties"); } if (typeMeta.Methods.Length > 0) { buffer.Append(" - "); buffer.Append(typeMeta.Methods.Length); buffer.Append(" methods"); } //buffer.Append(')'); this.typesLabel[i] = buffer.ToString(); } Utility.RestoreBuffer(buffer); } Event eventCurrent = Event.current; if (eventCurrent.type == EventType.MouseMove) { this.Repaint(); } for (int i = 0, max = assemblyMeta.Types.Length; i < max; ++i) { EditorGUILayout.LabelField(this.typesLabel[i]); Rect r = GUILayoutUtility.GetLastRect(); if (r.Contains(eventCurrent.mousePosition) == true) { r.xMin = r.xMax - 100F; if (GUI.Button(r, "Inspect") == true) { Utility.OpenWindow <TypeMetaWindow>(true, TypeMetaWindow.Title, true, null, w => w.typeMeta = assemblyMeta.Types[i]); return; } } } } } } }
public TypeDatabase(DatabaseMeta database) { Dictionary <string, Type> types = new Dictionary <string, Type>(); for (int i = 0, max = database.UnityMeta.Length; i < max; ++i) { UnityMeta unityMeta = database.UnityMeta[i]; for (int j = 0, max2 = unityMeta.AssembliesMeta.Length; j < max2; ++j) { AssemblyMeta assemblyMeta = unityMeta.AssembliesMeta[j]; for (int k = 0, max3 = assemblyMeta.Types.Length; k < max3; ++k) { TypeMeta typeMeta = assemblyMeta.Types[k]; Type type; if (types.TryGetValue(typeMeta.FullName, out type) == false) { type = new Type() { isPublic = typeMeta.IsPublic, name = typeMeta.FullName, members = new Member[0], versions = new byte[] { (byte)i } }; types.Add(typeMeta.FullName, type); } else { int l = 0; int max4 = type.versions.Length; for (; l < max4; ++l) { if (type.versions[l] == i) { break; } } if (l == max4) { Array.Resize(ref type.versions, type.versions.Length + 1); type.versions[type.versions.Length - 1] = (byte)i; } } for (int l = 0, max4 = typeMeta.Events.Length; l < max4; ++l) { type.Aggregate(MemberTypes.Event, typeMeta.Events[l].Name, i); } for (int l = 0, max4 = typeMeta.Properties.Length; l < max4; ++l) { type.Aggregate(MemberTypes.Property, typeMeta.Properties[l].Name, i); } for (int l = 0, max4 = typeMeta.Fields.Length; l < max4; ++l) { type.Aggregate(MemberTypes.Field, typeMeta.Fields[l].Name, i); } for (int l = 0, max4 = typeMeta.Methods.Length; l < max4; ++l) { type.Aggregate(MemberTypes.Method, typeMeta.Methods[l].Name, i); } } } } this.versions = new string[database.UnityMeta.Length]; for (int i = 0, max = database.UnityMeta.Length; i < max; ++i) { this.versions[i] = database.UnityMeta[i].Version; } this.types = new List <Type>(types.Values).ToArray(); }
public int RegisterType(TypeMeta meta) { return(this.typeTable.Register(meta)); }