private void DumpTag(NbtTag tag, int level, StreamWriter writer) { for (var index = 0; index < level; index++) writer.Write(" "); writer.Write(tag.Name); writer.Write(" ["); writer.Write(tag.GetType().Name); writer.Write("]: "); if (tag is NbtCompound) { writer.WriteLine("..."); foreach (var name in ((NbtCompound)tag).Names) { var value = tag[name]; this.DumpTag(value, level + 1, writer); } } else if (tag is NbtList) { writer.WriteLine("..."); foreach (var item in (NbtList)tag) this.DumpTag(item, level + 1, writer); } else writer.WriteLine(tag); }
public static T Get <T>(NbtCompound tag, string query) where T : NbtTag { if (!query.StartsWith("/")) { throw new ArgumentException("Not query string. (Start with slash.)"); } List <string> names = query.Substring(1).Split("/".ToCharArray()).ToList(); NbtTag result = tag; if (names[0] == result.Name) { names.RemoveAt(0); } else { return(null); } foreach (string name in names) { result = result[name]; } return((T)result); }
private void LoadFromStreamInternal([NotNull] Stream stream, [CanBeNull] TagSelector tagSelector) { var reader = new NbtBinaryReader(stream, BigEndian) { Selector = tagSelector, UseVarInt = UseVarInt }; RootTag = NbtTag.ReadUnknownTag(reader); //else { // // Make sure the first byte in this file is the tag for a TAG_Compound // int firstByte = stream.ReadByte(); // if (firstByte < 0) // { // throw new EndOfStreamException(); // } // if (firstByte != (int)NbtTagType.Compound) // { // throw new NbtFormatException("Given NBT stream does not start with a TAG_Compound"); // } // var rootCompound = new NbtCompound(reader.ReadString()); // rootCompound.ReadTag(reader); // RootTag = rootCompound; //} }
public override bool IsSameContentWith(NbtTag other) { if (!(other is NbtDouble tag)) { return(false); } return(tag.Value == Value); }
public override bool IsSameContentWith(NbtTag other) { if (!(other is NbtString str)) { return(false); } return(str.Value == Value); }
public override bool IsSameContentWith(NbtTag other) { if (!(other is NbtIntArray tag)) { return(false); } if (tag.Value.Length != Value.Length) { return(false); } return(Enumerable.SequenceEqual(tag.Value, Value)); }
void AddToParent([NotNull] NbtTag thisTag, [NotNull] NbtTag parent) { if (parent is NbtList parentAsList) { parentAsList.Add(thisTag); } else if (parent is NbtCompound parentAsCompound) { parentAsCompound.Add(thisTag); } else { // cannot happen unless NbtReader is bugged throw new NbtFormatException(InvalidParentTagError); } }
/// <summary> Writes a NbtTag object, and all of its child tags, to stream. /// Use this method sparingly with NbtWriter -- constructing NbtTag objects defeats the purpose of this class. /// If you already have lots of NbtTag objects, you might as well use NbtFile to write them all at once. </summary> /// <param name="tag"> Tag to write. Must not be null. </param> /// <exception cref="NbtFormatException"> No more tags can be written -OR- given tag is unacceptable at this time. </exception> /// <exception cref="ArgumentNullException"> <paramref name="tag"/> is null </exception> public void WriteTag(NbtTag tag) { if (tag == null) { throw new ArgumentNullException("tag"); } EnforceConstraints(tag.Name, tag.TagType); if (tag.Name != null) { tag.WriteTag(writer); } else { tag.WriteData(writer); } }
internal override void ReadTag(NbtBinaryReader readStream) { ListType = readStream.ReadTagType(); int length = readStream.ReadInt32(); if (length < 0) { throw new NbtFormatException("Negative list size given."); } for (int i = 0; i < length; i++) { NbtTag newTag = NbtTag.Construct(ListType); newTag.ReadTag(readStream); Tags.Add(newTag); } }
void AddToParent([NotNull] NbtTag thisTag, [NotNull] NbtTag parent) { var parentAsList = parent as NbtList; if (parentAsList != null) { parentAsList.Add(thisTag); } else { var parentAsCompound = parent as NbtCompound; if (parentAsCompound != null) { parentAsCompound.Add(thisTag); } else { // cannot happen unless NbtReader is bugged throw new NbtFormatException(InvalidParentTagError); } } }
public void Deserialize(NbtTag value) { NbtValue = value; }
/// <summary> Reads the entirety of the current tag, including any descendants, /// and constructs an NbtTag object of the appropriate type. </summary> /// <returns> Constructed NbtTag object; /// <c>null</c> if <c>SkipEndTags</c> is <c>true</c> and trying to read an End tag. </returns> /// <exception cref="NbtFormatException"> If an error occured while parsing data in NBT format. </exception> /// <exception cref="InvalidReaderStateException"> If NbtReader cannot recover from a previous parsing error. </exception> /// <exception cref="EndOfStreamException"> End of stream has been reached (no more tags can be read). </exception> /// <exception cref="InvalidOperationException"> Tag value has already been read, and CacheTagValues is false. </exception> public NbtTag ReadAsTag() { switch (state) { case NbtParseState.Error: throw new InvalidReaderStateException(ErroneousStateError); case NbtParseState.AtStreamEnd: throw new EndOfStreamException(); case NbtParseState.AtStreamBeginning: case NbtParseState.AtCompoundEnd: ReadToFollowing(); break; } NbtTag parent; if (TagType == NbtTagType.Compound) { parent = new NbtCompound(TagName); } else if (TagType == NbtTagType.List) { parent = new NbtList(TagName, ListType); } else if (atValue) { NbtTag result = ReadValueAsTag(); ReadToFollowing(); return(result); } else { throw new InvalidOperationException(NoValueToReadError); } int startingDepth = Depth; int lastDepth = Depth; do { bool end = !ReadToFollowing(); if (end || Depth < lastDepth) { // Going up the file tree, or end of document: wrap up while (Depth <= lastDepth && parent.Parent != null) { parent = parent.Parent; lastDepth--; } } if (end || Depth <= startingDepth) { break; } NbtTag thisTag; if (TagType == NbtTagType.Compound) { thisTag = new NbtCompound(TagName); AddToParent(thisTag, parent); parent = thisTag; } else if (TagType == NbtTagType.List) { thisTag = new NbtList(TagName, ListType); AddToParent(thisTag, parent); parent = thisTag; } else { thisTag = ReadValueAsTag(); AddToParent(thisTag, parent); } lastDepth = Depth; } while(true); return(parent); }
public void Deserialize(NbtTag value) { var compound = value as NbtCompound; var chunk = (Chunk)Serializer.Deserialize(value, true); this._TileEntities = chunk._TileEntities; this.Biomes = chunk.Biomes; this.HeightMap = chunk.HeightMap; this.LastUpdate = chunk.LastUpdate; this.Sections = chunk.Sections; this.TerrainPopulated = chunk.TerrainPopulated; this.X = chunk.X; this.Z = chunk.Z; // Entities var entities = compound["Entities"] as NbtList; Entities = new List<IDiskEntity>(); for (int i = 0; i < entities.Count; i++) { var id = entities[i]["id"].StringValue; IDiskEntity entity; if (EntityTypes.ContainsKey(id.ToUpper())) entity = (IDiskEntity)Activator.CreateInstance(EntityTypes[id]); else entity = new UnrecognizedEntity(id); entity.Deserialize(entities[i]); Entities.Add(entity); } var serializer = new NbtSerializer(typeof(Section)); foreach (var section in compound["Sections"] as NbtList) { int index = section["Y"].IntValue; Sections[index] = (Section)serializer.Deserialize(section); Sections[index].ProcessSection(); } }
/// <summary> Creates an empty NbtFile. /// RootTag will be set to an empty <c>NbtCompound</c> with a blank name (""). </summary> public NbtFile() { BigEndian = BigEndianByDefault; BufferSize = DefaultBufferSize; rootTag = new NbtCompound(""); }
public object Deserialize(NbtTag value, bool skipInterfaceCheck = false) { if (!skipInterfaceCheck && typeof(INbtSerializable).IsAssignableFrom(Type)) { var instance = (INbtSerializable)Activator.CreateInstance(Type); instance.Deserialize(value); return instance; } if (value is NbtByte) return ((NbtByte)value).Value; else if (value is NbtByteArray) return ((NbtByteArray)value).Value; else if (value is NbtDouble) return ((NbtDouble)value).Value; else if (value is NbtFloat) return ((NbtFloat)value).Value; else if (value is NbtInt) return ((NbtInt)value).Value; else if (value is NbtIntArray) return ((NbtIntArray)value).Value; else if (value is NbtLong) return ((NbtLong)value).Value; else if (value is NbtShort) return ((NbtShort)value).Value; else if (value is NbtString) return ((NbtString)value).Value; else if (value is NbtList) { var list = (NbtList)value; var type = typeof(object); if (list.ListType == NbtTagType.Byte) type = typeof(byte); else if (list.ListType == NbtTagType.ByteArray) type = typeof(byte[]); else if (list.ListType == NbtTagType.Compound) { if (Type.IsArray) type = Type.GetElementType(); else type = typeof(object); } else if (list.ListType == NbtTagType.Double) type = typeof(double); else if (list.ListType == NbtTagType.Float) type = typeof(float); else if (list.ListType == NbtTagType.Int) type = typeof(int); else if (list.ListType == NbtTagType.IntArray) type = typeof(int[]); else if (list.ListType == NbtTagType.Long) type = typeof(long); else if (list.ListType == NbtTagType.Short) type = typeof(short); else if (list.ListType == NbtTagType.String) type = typeof(string); else throw new NotSupportedException("The NBT list type '" + list.TagType + "' is not supported."); var array = Array.CreateInstance(type, list.Count); var innerSerializer = new NbtSerializer(type); for (int i = 0; i < array.Length; i++) array.SetValue(innerSerializer.Deserialize(list[i]), i); return array; } else if(value is NbtCompound) { var compound = value as NbtCompound; var properties = Type.GetProperties().Where(p => !Attribute.GetCustomAttributes(p, typeof(NbtIgnoreAttribute)).Any()); var resultObject = Activator.CreateInstance(Type); foreach (var property in properties) { if (!property.CanWrite) continue; string name = property.Name; var nameAttributes = Attribute.GetCustomAttributes(property, typeof(TagNameAttribute)); if (nameAttributes.Length != 0) name = ((TagNameAttribute)nameAttributes[0]).Name; var node = compound.Tags.SingleOrDefault(a => a.Name == name); if (node == null) continue; object data; if (typeof(INbtSerializable).IsAssignableFrom(property.PropertyType)) { data = Activator.CreateInstance(property.PropertyType); ((INbtSerializable)data).Deserialize(node); } else data = new NbtSerializer(property.PropertyType).Deserialize(node); // Some manual casting for edge cases if (property.PropertyType == typeof(bool) && data is byte) data = (byte)data == 1; if (property.PropertyType == typeof(sbyte) && data is byte) data = (sbyte)(byte)data; property.SetValue(resultObject, data, null); } return resultObject; } throw new NotSupportedException("The node type '" + value.GetType() + "' is not supported."); }
public abstract bool IsSameContentWith(NbtTag other);
public void Deserialize(NbtTag value) { Data = value.ByteArrayValue; }
public void Deserialize(NbtTag value) { var tag = (NbtCompound)value; X = tag["X"].IntValue; Z = tag["Z"].IntValue; if (tag.Contains("TerrainPopulated")) TerrainPopulated = tag["TerrainPopulated"].ByteValue > 0; if (tag.Contains("LightPopulated")) LightPopulated = tag["LightPopulated"].ByteValue > 0; Blocks = tag["Blocks"].ByteArrayValue; Metadata = new NibbleArray(); Metadata.Data = tag["Data"].ByteArrayValue; BlockLight = new NibbleArray(); BlockLight.Data = tag["BlockLight"].ByteArrayValue; SkyLight = new NibbleArray(); SkyLight.Data = tag["SkyLight"].ByteArrayValue; if (tag.Contains("TileEntities")) { foreach (var entity in tag["TileEntities"] as NbtList) { TileEntities[new Coordinates3D(entity["coordinates"][0].IntValue, entity["coordinates"][1].IntValue, entity["coordinates"][2].IntValue)] = entity["value"][0] as NbtCompound; } } UpdateHeightMap(); // TODO: Entities }
public NbtTag ReadAsTag() { switch (state) { case NbtParseState.Error: throw new InvalidReaderStateException(ErroneousStateError); case NbtParseState.AtStreamEnd: throw new EndOfStreamException(); case NbtParseState.AtStreamBeginning: case NbtParseState.AtCompoundEnd: ReadToFollowing(); break; } // get this tag NbtTag parent; if (TagType == NbtTagType.Compound) { parent = new NbtCompound(TagName); } else if (TagType == NbtTagType.List) { parent = new NbtList(TagName, ListType); } else if (atValue) { NbtTag result = ReadValueAsTag(); ReadToFollowing(); // if we're at a value tag, there are no child tags to read return(result); } else { // end tags cannot be read-as-tags (there is no corresponding NbtTag object) throw new InvalidOperationException(NoValueToReadError); } int startingDepth = Depth; int parentDepth = Depth; do { ReadToFollowing(); // Going up the file tree, or end of document: wrap up while (Depth <= parentDepth && parent.Parent != null) { parent = parent.Parent; parentDepth--; } if (Depth <= startingDepth) { break; } NbtTag thisTag; if (TagType == NbtTagType.Compound) { thisTag = new NbtCompound(TagName); AddToParent(thisTag, parent); parent = thisTag; parentDepth = Depth; } else if (TagType == NbtTagType.List) { thisTag = new NbtList(TagName, ListType); AddToParent(thisTag, parent); parent = thisTag; parentDepth = Depth; } else if (TagType != NbtTagType.End) { thisTag = ReadValueAsTag(); AddToParent(thisTag, parent); } } while (true); return(parent); }
public void Deserialize(NbtTag value) { var chunk = new Chunk(); var tag = (NbtCompound)value; Biomes = chunk.Biomes; HeightMap = chunk.HeightMap; LastUpdate = chunk.LastUpdate; TerrainPopulated = chunk.TerrainPopulated; X = tag["X"].IntValue; Z = tag["Z"].IntValue; Blocks = tag["Blocks"].ByteArrayValue; Metadata = new NibbleArray(); Metadata.Data = tag["Data"].ByteArrayValue; BlockLight = new NibbleArray(); BlockLight.Data = tag["BlockLight"].ByteArrayValue; SkyLight = new NibbleArray(); SkyLight.Data = tag["SkyLight"].ByteArrayValue; if (tag.Contains("TileEntities")) { foreach (var entity in tag["TileEntities"] as NbtList) { TileEntities[new Coordinates3D(entity["coordinates"][0].IntValue, entity["coordinates"][1].IntValue, entity["coordinates"][2].IntValue)] = entity["value"][0] as NbtCompound; } } // TODO: Entities }
public object Deserialize(NbtTag value) { if (value is NbtByte) return ((NbtByte)value).Value; else if (value is NbtByteArray) return ((NbtByteArray)value).Value; else if (value is NbtDouble) return ((NbtDouble)value).Value; else if (value is NbtFloat) return ((NbtFloat)value).Value; else if (value is NbtInt) return ((NbtInt)value).Value; else if (value is NbtIntArray) return ((NbtIntArray)value).Value; else if (value is NbtLong) return ((NbtLong)value).Value; else if (value is NbtShort) return ((NbtShort)value).Value; else if (value is NbtString) return ((NbtString)value).Value; else if(value is NbtCompound) { var compound = value as NbtCompound; var properties = Type.GetProperties().Where(p => !Attribute.GetCustomAttributes(p, typeof(NbtIgnoreAttribute)).Any()); var resultObject = Activator.CreateInstance(Type); foreach (var property in properties) { if (!property.CanWrite) continue; string name = property.Name; var nameAttributes = Attribute.GetCustomAttributes(property, typeof(TagNameAttribute)); if (nameAttributes.Length != 0) name = ((TagNameAttribute)nameAttributes[0]).Name; var node = compound.Tags.SingleOrDefault(a => a.Name == name); if (node == null) continue; var data = new NbtSerializer(property.PropertyType).Deserialize(node); if (property.PropertyType == typeof(bool) && data is byte) data = (byte)data == 1; property.SetValue(resultObject, data, null); } return resultObject; } throw new NotSupportedException("The node type '" + value.GetType() + "' is not supported."); }
static bool HeaderTagSelector( NbtTag tag ) { return tag.Parent == null || tag.Parent.Name != "MapData" || tag.Name != "BlockData"; }