/// <summary> /// Find the root elements and process their metadata. /// </summary> private void SetupSourceElements() { var rootElementRelativeOffset = BitConverter.ToInt32(this.CurrentDocument, RootElementOffsetOffset); var rootElement = Xmb2Element.FromByteArray(this.CurrentDocument, RootElementOffsetOffset + rootElementRelativeOffset); Debug.Assert(rootElement != null); var objectsElement = rootElement.GetElementByName("objects"); Debug.Assert(objectsElement != null); objectsElement.GetElements("object", this.ObjectElementList); if (this.ObjectElementList.Count > 0) { var firstElement = this.ObjectElementList[0]; var sourcePathElement = firstElement.GetElementByName("sourcePath_"); if (sourcePathElement != null) { this.SourcePath = sourcePathElement.GetTextValue(); } var nameElement = firstElement.GetElementByName("name_"); if (nameElement != null) { this.UniqueName = nameElement.GetTextValue(); } } this.UpdateListsByChecked(); this.UpdateListsByReference(); }
private void ReadField(SQEX.Luminous.Core.Object.BaseObject obj, Xmb2Element parentElement, uint hashedParentName, BaseObject objOffset) { if (objOffset != null) { obj = objOffset; } foreach (var element in parentElement.GetElements()) { var name = element.Name; var hashedName = Fnv1a.Fnv1a32(name, hashedParentName); var type = obj.GetObjectType(); if (type == null) { continue; } var property = type.PropertyContainer.FindByName(name); if (property == null) { continue; } this.ReadValue(obj, parentElement, element, property, hashedName, objOffset); } }
private BaseObject CreateDynamicBaseObject(Xmb2Element childElement) { var typeName = childElement.GetAttributeByName("type").GetTextValue(); var type = ObjectType.FindByFullName(typeName); return(type.ConstructFunction2()); }
private SQEX.Luminous.Core.Object.Object ReadObject(Xmb2Element element, out bool through) { through = false; string typeFullName = null; var typeAttribute = element.GetAttributeByName("type"); if (typeAttribute != null) { typeFullName = typeAttribute.GetTextValue(); } var type = ObjectType.FindByFullName(typeFullName); if (type == null) { return(null); } /*if (type == EntityPackage.ObjectType) * { * return null; * }*/ var instance = type.ConstructFunction2() as SQEX.Luminous.Core.Object.Object; if (instance != null) { through = true; } return(instance); }
/// <summary> /// Get the canonicalized source path of an element. /// </summary> /// <param name="element">The element.</param> /// <returns>The canonicalized source path.</returns> private string GetDataRelativePath(Xmb2Element element, EntityPackage parentPackage) { var sourcePathElement = element.GetElementByName("sourcePath_"); if (sourcePathElement == null) { return(null); } var isSharedElement = element.GetElementByName("isShared_"); if (isSharedElement?.GetBoolValue() == true) { return(null); } var sourcePath = sourcePathElement.GetTextValue(); if (sourcePath == null) { return(null); } //return sourcePath; // TODO Properly implement and debug if (parentPackage != null) { return(SQEX.Luminous.Core.IO.Path.ResolveRelativePath(parentPackage.sourcePath_, sourcePath)); } return(SQEX.Luminous.Core.IO.Path.ResolveRelativePath(this.SourcePath, sourcePath)); }
private void ReadValue(Luminous.Core.Object.BaseObject obj, Xmb2Element parentObject, Xmb2Element element, Property property, uint hashedName, BaseObject objOffset) { object value = null; switch (property.Type) { case Property.PrimitiveType.ClassField: this.ReadField(obj, element, Fnv1a.Fnv1a32(".", hashedName), obj.GetPropertyValue <BaseObject>(property)); break; case Property.PrimitiveType.Int8: case Property.PrimitiveType.Int16: case Property.PrimitiveType.Int32: case Property.PrimitiveType.Int64: case Property.PrimitiveType.UInt8: case Property.PrimitiveType.UInt16: case Property.PrimitiveType.UInt32: case Property.PrimitiveType.UInt64: case Property.PrimitiveType.INVALID2: case Property.PrimitiveType.Bool: case Property.PrimitiveType.Float: case Property.PrimitiveType.Double: case Property.PrimitiveType.String: case Property.PrimitiveType.Fixid: case Property.PrimitiveType.Vector4: case Property.PrimitiveType.Color: case Property.PrimitiveType.Enum: value = this.ReadPrimitiveValue(element, property); break; case Property.PrimitiveType.Pointer: if (this.ResolvePointer(parentObject, element, out value)) { // TODO addPointerListReferedBySequenceIfMatchCondition } break; case Property.PrimitiveType.PointerArray: case Property.PrimitiveType.IntrusivePointerArray: // GOTCHA: We don't want to create a new List, because other objects can reference the list before it's instantiated value = obj.GetPropertyValue <IList>(property); this.ReadPointerArray(obj, element, value as IList); break; default: if (property.Type != Property.PrimitiveType.Array) { throw new ArgumentException($"[EntityPackageXmlLoader]Unknown type {property.Type} for {property.Name}"); } break; } if (value != null) { obj.SetPropertyValue(property, value); } }
public static void Dump(byte[] xmb2, StringBuilder output) { var rootElementRelativeOffset = BitConverter.ToInt32(xmb2, RootElementOffsetOffset); var rootElement = Xmb2Element.FromByteArray(xmb2, RootElementOffsetOffset + rootElementRelativeOffset); Debug.Assert(rootElement != null); rootElement.Dump(xmb2, output, 0); }
private BaseObject ReadReference(Xmb2Element childElement, out int objectIndex) { objectIndex = -1; var referenceAttribute = childElement.GetAttributeByName("reference"); if (referenceAttribute == null) { return(null); } var objectIndexAttribute = childElement.GetAttributeByName("objectIndex"); if (objectIndexAttribute != null) { objectIndex = objectIndexAttribute.ToInt(-1); } if (objectIndex < 0) { return(null); } var referencedObject = this.GetObjectByIndex(objectIndex); if (referencedObject == null) { return(null); } var referencedObjectElement = this.GetObjectElementByIndex(objectIndex); if (referencedObjectElement == null) { return(null); } var relativePathAttribute = childElement.GetAttributeByName("relativePath"); if (relativePathAttribute == null) { return(referencedObject); } return(this.ReadReference(relativePathAttribute.GetTextValue(), referencedObject, referencedObjectElement)); }
private void ReadPointerArray(BaseObject obj, Xmb2Element element, IList destinationArray) { var itemCount = element.ElementCount; for (var i = 0; i < itemCount; i++) { var child = element.GetElementByIndex(i); if (child.GetAttributeByName("dynamic")?.ToBool() == true) { var dynamicInstance = CreateDynamicBaseObject(child); this.ReadDynamicBaseObjectChildElement(obj, dynamicInstance, child); destinationArray.Add(dynamicInstance); continue; } object itemValue = null; if (this.ResolvePointer(element, child, out itemValue)) { // TODO addPointerListReferedBySequenceIfMatchCondition destinationArray.Add(itemValue); } } }
/// <summary> /// Parse an XMB2 element into an object. /// </summary> /// <param name="element">The XMB2 element.</param> /// <param name="loadedObject">The parsed object.</param> /// <returns>True if the parse succeeded, else false.</returns> private bool ReadObject(Xmb2Element element) { bool through; var loadedObject = this.ReadObject(element, out through); var result = through; if (loadedObject != null) { this.Objects.Add(loadedObject); result = true; } else { // TEMP HACK loadedObject = new Entity(); this.Objects.Add(loadedObject); result = true; } this.LoadedObjectCount++; return(result); }
private object ReadPrimitiveValue(Xmb2Element element, Property property) { switch (property.Type) { case Property.PrimitiveType.Int8: return((sbyte)element.GetIntValue()); case Property.PrimitiveType.Int16: return((short)element.GetIntValue()); case Property.PrimitiveType.Int32: return(element.GetIntValue()); case Property.PrimitiveType.Int64: return((long)element.GetIntValue()); case Property.PrimitiveType.UInt8: return((byte)element.GetUIntValue()); case Property.PrimitiveType.UInt16: return((ushort)element.GetUIntValue()); case Property.PrimitiveType.UInt32: return(element.GetUIntValue()); case Property.PrimitiveType.UInt64: case Property.PrimitiveType.INVALID2: return((ulong)element.GetUIntValue()); case Property.PrimitiveType.Bool: return(element.GetBoolValue()); case Property.PrimitiveType.Float: return(element.GetFloatValue()); case Property.PrimitiveType.Double: return(element.GetDoubleValue()); case Property.PrimitiveType.String: return(element.GetTextValue()); case Property.PrimitiveType.Fixid: { var fixidAttribute = element.GetAttributeByName("fixid"); if (fixidAttribute != null) { return(fixidAttribute.ToUInt()); } return((uint)0); } case Property.PrimitiveType.Vector4: { var vector = element.GetFloat4Value(); if (vector != null) { return(new UnityEngine.Vector4(vector[0], vector[1], vector[2], vector[3])); } var strVector = element.GetTextValue(); var components = strVector.Split(',').ToList(); if (components.Count == 4) { return(new UnityEngine.Vector4(float.Parse(components[0]), float.Parse(components[1]), float.Parse(components[2]), float.Parse(components[3]))); } return(UnityEngine.Vector4.zero); } case Property.PrimitiveType.Color: { var vector = element.GetFloat4Value(); if (vector != null) { return(new UnityEngine.Color(vector[0], vector[1], vector[2], vector[3])); } var strVector = element.GetTextValue(); var components = strVector.Split(',').ToList(); if (components.Count == 4) { return(new UnityEngine.Color(float.Parse(components[0]), float.Parse(components[1]), float.Parse(components[2]), float.Parse(components[3]))); } return(UnityEngine.Color.black); } case Property.PrimitiveType.Enum: { var valueAttribute = element.GetAttributeByName("value"); if (valueAttribute != null) { return(valueAttribute.ToInt()); } return((uint)0); } default: return(null); } }
private BaseObject ReadReference(string relativePath, Luminous.Core.Object.Object destinationObject, Xmb2Element destinationObjectElement) { if (relativePath == null) { return(null); } var type = destinationObject.GetObjectType(); var property = type.PropertyContainer.FindByName(relativePath); if (property != null) { return(destinationObject.GetPropertyValue <BaseObject>(property)); } var relativePathSegments = relativePath.Split('.'); // TODO Commented out because not all types are implemented yet, causing this to misfire Debug.Assert(relativePathSegments.Length > 1, $"[EntityPackageXmlLoader]Reference relativePath not found {relativePath}"); if (relativePathSegments.Length == 1) { return(null); } property = type.PropertyContainer.FindByName(relativePathSegments[0]); if (property == null || property.Type != Property.PrimitiveType.ClassField || property.Type != Property.PrimitiveType.PointerArray) { Debug.Fail($"[EntityPackageXmlLoader]Reference relativePath not found {relativePath}"); return(null); } var referencedPropertyValue = destinationObject.GetPropertyValue <Luminous.Core.Object.Object>(property); var referencedPropertyElement = destinationObjectElement.GetElementByName(relativePathSegments[0]); if (referencedPropertyElement == null) { Debug.Fail($"[EntityPackageXmlLoader]Reference relativePath not found {relativePath}"); return(null); } if (property.Type != Property.PrimitiveType.PointerArray) { var referencedPropertyElementTypeAttribute = referencedPropertyElement.GetAttributeByName("type"); if (referencedPropertyElementTypeAttribute == null || referencedPropertyElementTypeAttribute.GetTextValue() != "enum") { return(this.ReadReference(relativePathSegments[1], referencedPropertyValue, referencedPropertyElement)); } else { Debug.Fail($"[EntityPackageXmlLoader]Reference relativePath not found {relativePath}"); return(null); } } // TODO read pointer array item //return this.ReadReference(relativePath, destinationObject, destinationObjectElement); return(null); }
private bool ResolvePointer(Xmb2Element parentElement, Xmb2Element childElement, out object destination) { int referencedObjectIndex = 0; destination = this.ReadReference(childElement, out referencedObjectIndex); if (destination != null) { return(true); } var isPointerType = false; var typeAttribute = childElement.GetAttributeByName("type"); if (typeAttribute != null) { var type = typeAttribute.GetTextValue(); if (type == "pointer") { isPointerType = true; } } /*TODO * bool result; * if (!isPointerType && this.TryRegisterExternalPointerInfoAsSubPackage(destination, referencedObjectIndex, out result) * { * return result; * }*/ if (this.UncheckedObjectIndices.Contains(referencedObjectIndex)) { return(false); } if (this.StartupUnloadObjectIndexes.Contains(referencedObjectIndex)) { return(false); } var useUnresolvedPointerReferenceAttribute = childElement.GetAttributeByName("UseUnresolvedPointerReference"); if (useUnresolvedPointerReferenceAttribute?.ToBool() != true) { var resolvedReferenceAttribute = childElement.GetAttributeByName("object"); if (isPointerType) { Debug.Assert(resolvedReferenceAttribute == null, $"[EntityPackageXmlLoader] ResolvedReference not found : object path={resolvedReferenceAttribute.GetTextValue()}"); } else { var useTemplateConnectionAttribute = childElement.GetAttributeByName("UseTemplateConnection"); var unknownFlagAttribute = childElement.GetAttributeByName(4262871454); if (useTemplateConnectionAttribute?.ToBool() == true || unknownFlagAttribute?.ToBool() == true) { var prefabConnectionRelativePathAttribute = childElement.GetAttributeByName("relativePath"); var targetPackageSourcePathAttribute = childElement.GetAttributeByName("targetPackageSourcePath"); var proxyConnectionOwnerPackageNameAttribute = childElement.GetAttributeByName("ProxyConnectionOwnerPackageName"); Debug.Assert(prefabConnectionRelativePathAttribute != null, $"[EntityPackageXmlLoader] Prefab Connection : relativePath is null : object path={resolvedReferenceAttribute.GetTextValue()}, targetPackageSourcePath={targetPackageSourcePathAttribute.GetTextValue()}"); Debug.Assert(useTemplateConnectionAttribute?.ToBool() != true || proxyConnectionOwnerPackageNameAttribute?.ToBool() != false, $"[EntityPackageXmlLoader] Template Connection : targetPackageName is null : object path={resolvedReferenceAttribute.GetTextValue()}, targetPackageSourcePath={targetPackageSourcePathAttribute.GetTextValue()}"); var templateConnectionRelativePathAttribute = childElement.GetAttributeByName("relativePath"); var prefabConnectionSourceItemPathAttribute = childElement.GetAttributeByName("PrefabConnectionSourceItemPath"); ushort templateConnectionProtocol = 6; if (useTemplateConnectionAttribute?.ToBool() == false) { templateConnectionProtocol = 4; } var templateConnectionExternalPointerInfo = new ExternalPointerInfo(templateConnectionProtocol, destination); this.Result.ExternalPointerInfos.Add(templateConnectionExternalPointerInfo); templateConnectionExternalPointerInfo.AddKey(targetPackageSourcePathAttribute?.GetTextValue()); templateConnectionExternalPointerInfo.AddKey(proxyConnectionOwnerPackageNameAttribute?.GetTextValue()); templateConnectionExternalPointerInfo.AddKey(resolvedReferenceAttribute?.GetTextValue()); templateConnectionExternalPointerInfo.AddKey(templateConnectionRelativePathAttribute?.GetTextValue()); templateConnectionExternalPointerInfo.AddKey(prefabConnectionSourceItemPathAttribute?.GetTextValue()); templateConnectionExternalPointerInfo.AddKey(this.SourcePath); return(true); } Debug.Assert(resolvedReferenceAttribute?.GetTextValue() != null, "[EntityPackageXmlLoader] reference not found : object path is null"); Debug.Assert(resolvedReferenceAttribute?.GetTextValue() != "INVALID_CONNECTOR", $"[EntityPackageXmlLoader] reference not found : object path={parentElement.GetAttributeByName("path")?.GetTextValue()}, reference path={resolvedReferenceAttribute.GetTextValue()}"); } return(false); } var farReferenceAttribute = childElement.GetAttributeByName("FarReference"); var objectAttribute = childElement.GetAttributeByName("object"); var relativePathAttribute = childElement.GetAttributeByName("relativePath"); var unknownKeyAttribute = childElement.GetAttributeByName(347410431); var unresolvedPointerPackageSourceAttribute = childElement.GetAttributeByName("UnresolvedPointerPackageSource"); ushort protocol = 7; if (farReferenceAttribute?.ToBool() == false) { protocol = 1; } var externalPointerInfo = new ExternalPointerInfo(protocol, destination); this.Result.ExternalPointerInfos.Add(externalPointerInfo); externalPointerInfo.AddKey(unresolvedPointerPackageSourceAttribute?.GetTextValue()); externalPointerInfo.AddKey(objectAttribute?.GetTextValue()); externalPointerInfo.AddKey(relativePathAttribute?.GetTextValue()); externalPointerInfo.AddKey(unknownKeyAttribute?.GetTextValue()); externalPointerInfo.AddKey(this.SourcePath); if (farReferenceAttribute?.ToBool() == true) { externalPointerInfo.AddKey(childElement.GetAttributeByName(1280569575).GetTextValue()); } return(true); }
private void ReadDynamicBaseObjectChildElement(BaseObject parentObject, BaseObject baseObject, Xmb2Element childElement) { foreach (var element in childElement.GetElements()) { var name = element.Name; var hashedName = Fnv1a.Fnv1a32(name, 2166136261); // ??? var type = baseObject.GetObjectType(); if (type == null) { continue; } var property = type.PropertyContainer.FindByName(name); if (property == null) { continue; } this.ReadValue(baseObject, childElement, element, property, hashedName, baseObject); } }
private EntityPackage CreatePackage() { EntityPackage package = null; if (this.CurrentDocument == null) { return(null); } this.LoadStatus = LOAD_STATUS.LOAD_ST_LOAD; var rootElementRelativeOffset = BitConverter.ToInt32(this.CurrentDocument, RootElementOffsetOffset); var rootElement = Xmb2Element.FromByteArray(this.CurrentDocument, RootElementOffsetOffset + rootElementRelativeOffset); var objectsElement = rootElement.GetElementByName("objects"); if (objectsElement == null || this.LoadedObjectCount >= this.ObjectElementList.Count) { this.LoadStatus = LOAD_STATUS.LOAD_ST_CREATE; // TODO goto LABEL_28; } // Instantiate each object. for (int i = (int)this.LoadedObjectCount; i < this.ObjectElementList.Count; i++) { var element = this.ObjectElementList[i]; var objectIndex = 0; var objectIndexAttribute = element.GetAttributeByName("objectIndex"); if (objectIndexAttribute != null) { objectIndex = objectIndexAttribute.ToInt(); } this.ObjectIndexMap.Add(objectIndex, i); if (!this.ReadObject(element)) { break; } } // Read each object's fields. for (int i = 0; i < this.ObjectElementList.Count; i++) { var element = this.ObjectElementList[i]; var obj = this.Objects[i]; if (this.Objects[i] is EntityPackage) { package = obj as EntityPackage; package.sourcePath_ = this.GetDataRelativePath(element, package); } this.ReadField(obj, element, 2166136261, null); // "" if (!(this.Objects[i] is EntityPackage)) { var ownerIndexAttribute = element.GetAttributeByName("ownerIndex"); var ownerIndex = 0; if (ownerIndexAttribute != null) { ownerIndex = ownerIndexAttribute.ToInt(); } } string name = null; var nameAttribute = element.GetAttributeByName("name"); if (nameAttribute != null) { name = nameAttribute.GetTextValue(); if (this.Objects[i] is EntityPackage) { package.simpleName_ = name; } } string objPath = null; var pathAttribute = element.GetAttributeByName("path"); if (pathAttribute != null) { objPath = pathAttribute.GetTextValue(); } package.AddLoadedObject(obj, name, objPath); } this.LoadStatus = LOAD_STATUS.LOAD_ST_CREATE; return(package); }