/// <summary> /// Returns true if given tree exactly matches this one /// </summary> /// <param name="other"></param> /// <returns></returns> public bool Equals(IWorldAccessor worldForResolve, IAttribute other) { if (!(other is TreeAttribute)) { return(false); } TreeAttribute otherTree = (TreeAttribute)other; if (attributes.Count != otherTree.attributes.Count) { return(false); } foreach (var val in attributes) { if (!otherTree.attributes.ContainsKey(val.Key)) { return(false); } if (!otherTree.attributes[val.Key].Equals(worldForResolve, val.Value)) { return(false); } } return(true); }
public static TreeAttribute CreateFromBytes(byte[] blockEntityData) { TreeAttribute tree = new TreeAttribute(); using (MemoryStream ms = new MemoryStream(blockEntityData)) { using (BinaryReader reader = new BinaryReader(ms)) { tree.FromBytes(reader); } } return(tree); }
/// <summary> /// Returns true if given tree contains all of elements of this one, but given tree may contain also more elements. Individual node values are exactly matched. /// </summary> /// <param name="other"></param> /// <returns></returns> public bool IsSubSetOf(IWorldAccessor worldForResolve, IAttribute other) { if (!(other is TreeAttribute)) { return(false); } TreeAttribute otherTree = (TreeAttribute)other; if (attributes.Count > otherTree.attributes.Count) { return(false); } foreach (var val in attributes) { if (GlobalConstants.IgnoredStackAttributes.Contains(val.Key)) { continue; } if (!otherTree.attributes.ContainsKey(val.Key)) { return(false); } if (val.Value is TreeAttribute) { if (!(otherTree.attributes[val.Key] as TreeAttribute).IsSubSetOf(worldForResolve, val.Value)) { return(false); } } else { if (!otherTree.attributes[val.Key].Equals(worldForResolve, val.Value)) { return(false); } } } return(true); }
/// <summary> /// Retrieves an attribute tree or adds it if key is not found. /// Throws an exception if the key does exist but is not a tree. /// </summary> /// <param name="key"></param> /// <returns></returns> public virtual ITreeAttribute GetOrAddTreeAttribute(string key) { var attr = attributes.TryGetValue(key); if (attr == null) { var result = new TreeAttribute(); SetAttribute(key, result); return(result); } else if (attr is ITreeAttribute result) { return(result); } else { throw new InvalidOperationException( $"The attribute with key '{ key }' is a { attr.GetType().Name }, not TreeAttribute."); } }
static IAttribute ToAttribute(JToken token) { JValue jval = token as JValue; // Scalar if (jval != null) { if (jval.Value is int) { return(new IntAttribute((int)jval.Value)); } if (jval.Value is long) { return(new LongAttribute((long)jval.Value)); } if (jval.Value is float) { return(new FloatAttribute((float)jval.Value)); } if (jval.Value is double) { return(new DoubleAttribute((double)jval.Value)); } if (jval.Value is bool) { return(new BoolAttribute((bool)jval.Value)); } if (jval.Value is string) { return(new StringAttribute((string)jval.Value)); } } // Object, but an itemstack? /*JObject jobj = token as JObject; * if (jobj != null) * { * if (jobj["type"] != null && jobj["code"] != null) * { * JValue typeVal = jobj["type"] as JValue; * if (typeVal != null && typeVal.Value is string) * { * * } * } * * return tree; * }*/ // Object JObject jobj = token as JObject; if (jobj != null) { TreeAttribute tree = new TreeAttribute(); foreach (var val in jobj) { tree[val.Key] = ToAttribute(val.Value); } return(tree); } // Array JArray jarr = token as JArray; if (jarr != null) { if (!jarr.HasValues) { return(new TreeArrayAttribute(new TreeAttribute[0])); } JToken first = jarr[0]; JValue jvalFirst = first as JValue; if (jvalFirst != null) { if (jvalFirst.Value is int) { return(new IntArrayAttribute(ToPrimitiveArray <int>(jarr))); } if (jvalFirst.Value is long) { return(new LongArrayAttribute(ToPrimitiveArray <long>(jarr))); } if (jvalFirst.Value is float) { return(new FloatArrayAttribute(ToPrimitiveArray <float>(jarr))); } if (jvalFirst.Value is double) { return(new DoubleArrayAttribute(ToPrimitiveArray <double>(jarr))); } if (jvalFirst.Value is bool) { return(new BoolArrayAttribute(ToPrimitiveArray <bool>(jarr))); } if (jvalFirst.Value is string) { return(new StringArrayAttribute(ToPrimitiveArray <string>(jarr))); } return(null); } TreeAttribute[] attrs = new TreeAttribute[jarr.Count]; for (int i = 0; i < attrs.Length; i++) { attrs[i] = (TreeAttribute)ToAttribute(jarr[i]); } return(new TreeArrayAttribute(attrs)); } return(null); }
public bool Equals(IWorldAccessor worldForResolve, IAttribute other, string currentPath, params string[] ignorePaths) { if (!(other is TreeAttribute)) { return(false); } TreeAttribute otherTree = (TreeAttribute)other; if ((ignorePaths == null || ignorePaths.Length == 0) && attributes.Count != otherTree.attributes.Count) { return(false); } // Test 1 and 2: // - Check for exists in a, but missing in b // - Check for a != b foreach (var val in attributes) { string curPath = currentPath + (currentPath.Length > 0 ? "/" : "") + val.Key; if (ignorePaths != null && ignorePaths.Contains(curPath)) { continue; } if (!otherTree.attributes.ContainsKey(val.Key)) { return(false); } IAttribute otherAttr = otherTree.attributes[val.Key]; if (otherAttr is TreeAttribute) { if (!((TreeAttribute)otherAttr).Equals(worldForResolve, val.Value, currentPath, ignorePaths)) { return(false); } } else { if (otherAttr is ItemstackAttribute) { if (!(otherAttr as ItemstackAttribute).Equals(worldForResolve, val.Value, ignorePaths)) { return(false); } } else { if (!otherAttr.Equals(worldForResolve, val.Value)) { return(false); } } } } // Test 3: // - Check for exists in b, but missing in a foreach (var val in otherTree.attributes) { string curPath = currentPath + (currentPath.Length > 0 ? "/" : "") + val.Key; if (ignorePaths != null && ignorePaths.Contains(curPath)) { continue; } if (!attributes.ContainsKey(val.Key)) { return(false); } } return(true); }
public IAttribute ToAttribute(IWorldAccessor resolver) { if (type == EnumAttributeType.Unknown) { if (elems != null) { type = EnumAttributeType.Tree; } else if (values != null) { type = EnumAttributeType.StringArray; } else { type = EnumAttributeType.String; } } switch (type) { case EnumAttributeType.Bool: { return(new BoolAttribute(value == "true")); } case EnumAttributeType.Int: { int val = 0; int.TryParse(value, out val); return(new IntAttribute(val)); } case EnumAttributeType.Double: { double val = 0; double.TryParse(value, out val); return(new DoubleAttribute(val)); } case EnumAttributeType.Float: { float val = 0; float.TryParse(value, NumberStyles.Any, GlobalConstants.DefaultCultureInfo, out val); return(new FloatAttribute(val)); } case EnumAttributeType.String: return(new StringAttribute(value)); case EnumAttributeType.StringArray: return(new StringArrayAttribute(values)); case EnumAttributeType.Tree: ITreeAttribute tree = new TreeAttribute(); if (elems == null) { return(tree); } foreach (var val in elems) { IAttribute attribute = val.Value.ToAttribute(resolver); if (attribute == null) { continue; } tree[val.Key] = attribute; } return(tree); case EnumAttributeType.Itemstack: if (elems == null) { return(null); } bool haveClass = elems.ContainsKey("class") && elems["class"].type == EnumAttributeType.String; bool haveItemCode = elems.ContainsKey("code") && elems["code"].type == EnumAttributeType.String; bool haveStackSize = elems.ContainsKey("quantity") && elems["quantity"].type == EnumAttributeType.Int; if (!haveClass || !haveItemCode || !haveStackSize) { return(null); } EnumItemClass itemclass; try { itemclass = (EnumItemClass)Enum.Parse(typeof(EnumItemClass), elems["class"].value); } catch (Exception) { return(null); } int quantity = 0; if (!int.TryParse(elems["quantity"].value, out quantity)) { return(null); } ItemStack itemstack; if (itemclass == EnumItemClass.Block) { Block block = resolver.GetBlock(new AssetLocation(elems["code"].value)); if (block == null) { return(null); } itemstack = new ItemStack(block, quantity); } else { Item item = resolver.GetItem(new AssetLocation(elems["code"].value)); if (item == null) { return(null); } itemstack = new ItemStack(item, quantity); } if (elems.ContainsKey("attributes")) { IAttribute attributes = elems["attributes"].ToAttribute(resolver); if (attributes is ITreeAttribute) { itemstack.Attributes = (ITreeAttribute)attributes; } } return(new ItemstackAttribute(itemstack)); } return(null); }