/// <summary> /// Returns this entity's data without its entity type /// </summary> /// <returns>This entity's data without its entity type</returns> public string GetDataWithoutID() { Data.DataPartObject dataObject = GetDataTree(); Data.DataPartPath? idPath = dataObject.GetValues().SingleOrDefault(p => p.PathName == "id"); if (!(idPath is null)) { idPath.PathValue = new Data.DataPartTag(null); } return(dataObject.GetDataString()); }
/// <summary> /// Merges this <see cref="DataPartObject"/> together with another <see cref="DataPartObject"/> /// </summary> /// <param name="mergeWith">The other <see cref="DataPartObject"/> to merge with</param> public void MergeDataPartObject(DataPartObject mergeWith) { if (mergeWith is null) { throw new ArgumentNullException(nameof(mergeWith), "MergeWith may not be null."); } foreach (DataPartPath path in mergeWith.values) { DataPartPath existingPath = values.SingleOrDefault(d => d.PathName == path.PathName); if (existingPath is null) { AddValue(path); } else { if (existingPath.PathValue is DataPartObject addToObject && path.PathValue is DataPartObject addObject) { addToObject.MergeDataPartObject(addObject); }
/// <summary> /// Returns a tree structure containing all the data tags for this object /// </summary> /// <returns>the bottom of the tree</returns> public virtual DataPartObject GetDataTree() { List <PropertyInfo> dataProperties = GetDataProperties().ToList(); DataPartObject rootObject = new DataPartObject(false); foreach (PropertyInfo property in dataProperties) { object?data = property.GetValue(this); if (data is null) { continue; } //get property full path and go through each part and add it to the end DataTagAttribute dataTagInformation = (DataTagAttribute)property.GetCustomAttribute(typeof(DataTagAttribute)) !; string fullPath = dataTagInformation.DataTagName ?? property.Name; DataPartObject pathAtLocation = rootObject; string[] pathParts = fullPath.Split('.'); for (int i = 0; i < pathParts.Length; i++) { if (i == pathParts.Length - 1) { //path ends DataPartPath addToPath = pathAtLocation.GetValues().SingleOrDefault(p => p.PathName == pathParts[i]); if (addToPath is null) { //Path doesn't exist yet //Path can be an object, array or tag ID.NBTTagType? forceType = dataTagInformation.UseForcedType ? dataTagInformation.ForceType : (ID.NBTTagType?)null; object?[] conversionData = dataTagInformation.ConversionParams; IConvertableToDataTag? convertAbleTag = data as IConvertableToDataTag; IConvertableToDataArrayBase?convertAbleArray = data as IConvertableToDataArrayBase; IConvertableToDataObject? convertAbleObject = data as IConvertableToDataObject; if ((property.GetValue(this) is DataHolderBase && forceType is null) || forceType == ID.NBTTagType.TagCompound || (!(convertAbleObject is null) && forceType is null)) { //if its an object DataHolderBase?dataObject = property.GetValue(this) as DataHolderBase; if (!(convertAbleObject is null) && ((!(dataObject is null) && conversionData.Length != 0) || dataObject is null)) { try { if (dataTagInformation.Merge) { pathAtLocation.MergeDataPartObject(convertAbleObject.GetAsDataObject(conversionData)); } else { pathAtLocation.AddValue(new DataPartPath(pathParts[i], convertAbleObject.GetAsDataObject(conversionData), dataTagInformation.JsonTag)); } } catch (Exception ex) { throw new InvalidCastException($"Failed to convert {property.Name} for {GetType().FullName} into a data tag object (See inner exception)", ex); } } else if (!(dataObject is null)) { if (dataTagInformation.Merge) { pathAtLocation.MergeDataPartObject(dataObject.GetDataTree()); } else { pathAtLocation.AddValue(new DataPartPath(pathParts[i], dataObject.GetDataTree(), dataTagInformation.JsonTag)); } } else if (!(convertAbleTag is null)) { try { pathAtLocation.AddValue(new DataPartPath(pathParts[i], convertAbleTag.GetAsTag(forceType, conversionData), dataTagInformation.JsonTag)); } catch (Exception ex) { throw new InvalidCastException($"Failed to convert {property.Name} for {GetType().FullName} into a data tag (See inner exception)", ex); } }