public override NbtCompound ToNBT() { NbtCompound c = new NbtCompound(); Base2NBT(ref c,GetID()); c.Tags.Add(new NbtByte("Tile", Tile)); return c; }
public override void SetCompound(NbtCompound compound) { Line1 = GetTextValue(compound, "Text1"); Line2 = GetTextValue(compound, "Text2"); Line3 = GetTextValue(compound, "Text3"); Line4 = GetTextValue(compound, "Text4"); }
public void ErrorTest() { var root = new NbtCompound("root"); byte[] testData = new NbtFile(root).SaveToBuffer(NbtCompression.None); // creating NbtReader without a stream, or with a non-readable stream Assert.Throws<ArgumentNullException>(() => new NbtReader(null)); Assert.Throws<ArgumentException>(() => new NbtReader(new NonReadableStream())); // corrupt the data testData[0] = 123; var reader = new NbtReader(new MemoryStream(testData)); // attempt to use ReadValue when not at value Assert.Throws<InvalidOperationException>(() => reader.ReadValue()); reader.CacheTagValues = true; Assert.Throws<InvalidOperationException>(() => reader.ReadValue()); // attempt to read a corrupt stream Assert.Throws<NbtFormatException>(() => reader.ReadToFollowing()); // make sure we've properly entered the error state Assert.IsTrue(reader.IsInErrorState); Assert.IsFalse(reader.HasName); Assert.Throws<InvalidReaderStateException>(() => reader.ReadToFollowing()); Assert.Throws<InvalidReaderStateException>(() => reader.ReadListAsArray<int>()); Assert.Throws<InvalidReaderStateException>(() => reader.ReadToNextSibling()); Assert.Throws<InvalidReaderStateException>(() => reader.ReadToDescendant("derp")); Assert.Throws<InvalidReaderStateException>(() => reader.ReadAsTag()); Assert.Throws<InvalidReaderStateException>(() => reader.Skip()); }
public override NbtCompound ToNBT() { NbtCompound c = new NbtCompound(); Base2NBT(ref c); c.Tags.Add(Inventory.ToNBT()); return c; }
public void SkippingLists() { { var file = new NbtFile(TestFiles.MakeListTest()); byte[] savedFile = file.SaveToBuffer(NbtCompression.None); file.LoadFromBuffer(savedFile, 0, savedFile.Length, NbtCompression.None, tag => tag.TagType != NbtTagType.List); Assert.AreEqual(0, file.RootTag.Count); } { // Check list-compound interaction NbtCompound comp = new NbtCompound("root") { new NbtCompound("compOfLists") { new NbtList("listOfComps") { new NbtCompound { new NbtList("emptyList", NbtTagType.Compound) } } } }; var file = new NbtFile(comp); byte[] savedFile = file.SaveToBuffer(NbtCompression.None); file.LoadFromBuffer(savedFile, 0, savedFile.Length, NbtCompression.None, tag => tag.TagType != NbtTagType.List); Assert.AreEqual(1, file.RootTag.Count); } }
public FurnaceBlockEntity() : base("Furnace") { UpdatesOnTick = true; Compound = new NbtCompound(string.Empty) { new NbtString("id", Id), new NbtList("Items", new NbtCompound()), new NbtInt("x", Coordinates.X), new NbtInt("y", Coordinates.Y), new NbtInt("z", Coordinates.Z) }; NbtList items = (NbtList) Compound["Items"]; for (byte i = 0; i < 3; i++) { items.Add(new NbtCompound() { new NbtByte("Count", 0), new NbtByte("Slot", i), new NbtShort("id", 0), new NbtByte("Damage", 0), }); } }
public static McEntity LoadEntity(NbtCompound entity) { if (entity["id"] != null && entity["id"] is NbtString) { switch (((NbtString) entity["id"]).Value.ToLower()) { case "mob": McEntityMob mob = new McEntityMob(); mob.LoadEntity(entity); return mob; case "item": McEntityItem item = new McEntityItem(); item.LoadEntity(entity); return item; case "localplayer": McEntityLocalPlayer player = new McEntityLocalPlayer(); player.LoadEntity(entity); return player; default: Console.WriteLine("Unknown Entity: {0}", ((NbtString) entity["id"]).Value); break; } } return null; }
public override void SetCompound(NbtCompound compound) { Text1 = GetTextValue(compound, "Text1"); Text2 = GetTextValue(compound, "Text2"); Text3 = GetTextValue(compound, "Text3"); Text4 = GetTextValue(compound, "Text4"); }
public UpdateTileEntityPacket(Vector3 position, TileEntityAction action, NbtCompound data) { Data = new NbtFile(); Data.RootTag = data; Position = position; Action = action; }
public void AddingAndRemoving() { NbtCompound test = new NbtCompound(); NbtInt foo = new NbtInt( "Foo" ); test.Add( foo ); // adding duplicate object Assert.Throws<ArgumentException>( () => test.Add( foo ) ); // adding duplicate name Assert.Throws<ArgumentException>( () => test.Add( new NbtByte( "Foo" ) ) ); // adding unnamed tag Assert.Throws<ArgumentException>( () => test.Add( new NbtInt() ) ); // adding null Assert.Throws<ArgumentNullException>( () => test.Add( null ) ); // contains existing name Assert.IsTrue( test.Contains( "Foo" ) ); // contains existing object Assert.IsTrue( test.Contains( foo ) ); // contains non-existent name Assert.IsFalse( test.Contains( "Bar" ) ); // contains existing name / different object Assert.IsFalse( test.Contains( new NbtInt( "Foo" ) ) ); // removing non-existent name Assert.IsFalse( test.Remove( "Bar" ) ); // removing existing name Assert.IsTrue( test.Remove( "Foo" ) ); // removing non-existent name Assert.IsFalse( test.Remove( "Foo" ) ); // re-adding object test.Add( foo ); // removing existing object Assert.IsTrue( test.Remove( foo ) ); // clearing an empty NbtCompound Assert.AreEqual( test.Count, 0 ); test.Clear(); // re-adding after clearing test.Add( foo ); Assert.AreEqual( test.Count, 1 ); // clearing a non-empty NbtCompound test.Clear(); Assert.AreEqual( test.Count, 0 ); }
public LivingEntity(NbtCompound c) { SetBaseStuff(c); Health = (c["Health"] as NbtShort).Value; HurtTime = (c["HurtTime"] as NbtShort).Value; AttackTime = (c["AttackTime"] as NbtShort).Value; DeathTime = (c["DeathTime"] as NbtShort).Value; }
public override NbtCompound ToNBT() { NbtCompound c = new NbtCompound(); Base2NBT(ref c); c.Tags.Add(new NbtString("EntityId", EntityId)); c.Tags.Add(new NbtShort("Delay", Delay)); return c; }
public NbtCompound ToNBT() { NbtCompound c = new NbtCompound(); Base2NBT(ref c,GetID()); c.Tags.Add(new NbtByte("Tile", Tile)); c.Tags.Add(new NbtByte("OnGround", OnGround)); return c; }
public void Save() { //Create nbt file var file = new NbtFile(); var data = new NbtCompound() {Name = "Data"}; file.RootTag.Add(data); }
public NbtCompound Read(NbtCompound metadata) { Tags = new NbtTag[metadata.Tags.Count()]; metadata.CopyTo(Tags, 0); foreach (NbtTag b in Tags) metadata.Remove(b); return metadata; }
/// <summary> /// Load a TileEntity's basic values (call via base() in all inheriting files) /// </summary> /// <param name="CX">Chunk X Coordinate</param> /// <param name="CY">Chunk Y Coordinate</param> /// <param name="CS">Chunk horizontal scale</param> /// <param name="c">TileEntity's NbtCompound.</param> public TileEntity(int CX,int CY,int CS,NbtCompound c) { Pos = new Vector3i( c.Get<NbtInt>("x").Value, c.Get<NbtInt>("y").Value, c.Get<NbtInt>("z").Value); ID = (c["id"] as NbtString).Value; orig = c; }
/// <summary> /// Load a TileEntity's basic values (call via base() in all inheriting files) /// </summary> /// <param name="c"></param> public TileEntity(NbtCompound c) { orig = c; Pos = new Vector3i( c.Get<NbtInt>("x").Value, c.Get<NbtInt>("z").Value, c.Get<NbtInt>("y").Value); id = c.Get<NbtString>("id").Value; }
public NbtCompound Write() { var Base = new NbtCompound("MCForge") { new NbtByte("perbuild", perbuild), new NbtByte("pervisit", pervisit) }; return Base; }
public override NbtCompound ToNBT() { NbtCompound c = new NbtCompound(); Base2NBT(ref c,GetID()); c.Tags.Add(new NbtShort("Health", Health)); c.Tags.Add(new NbtShort("HurtTime", HurtTime)); c.Tags.Add(new NbtShort("AttackTime", AttackTime)); c.Tags.Add(new NbtShort("DeathTime", DeathTime)); return c; }
public void HugeNbtFileTest() { byte[] val = new byte[1024*1024*1024]; NbtCompound root = new NbtCompound("root") { new NbtByteArray("payload1") { Value = val } }; NbtFile file = new NbtFile(root); file.SaveToStream(Stream.Null, NbtCompression.None); }
public Area(NbtCompound cmpd) { name = cmpd.Get<NbtString>("name").Value; NbtList ground = cmpd.Get<NbtList>("ground"); foreach(NbtCompound alpha in ground) { int x = alpha.Get<NbtByte>("x").Value; int y = alpha.Get<NbtByte>("y").Value; platformMap.Add(new Point(x, y)); } Map.portalsToProcess[this] = cmpd.Get<NbtList>("portal").ToArray<NbtCompound>().ToList<NbtCompound>(); }
public override NbtCompound ToNBT() { NbtCompound c = new NbtCompound(); Base2NBT(ref c); for (int i = 0; i < 4; i++) { string tagID = string.Format("Text{0}", i + 1); c.Add(new NbtString(tagID, Text[i])); } return c; }
public Entity(NbtCompound c) { orig = c; id = (orig["id"] as NbtString).Value; SetBaseStuff(c); #if DEBUG Console.WriteLine("*** BUG: Unknown entity (ID: {0})",id); Console.WriteLine(orig); #endif File.WriteAllText("UnknownEntity." + id + ".txt", orig.ToString().Replace("\n","\r\n")); }
internal NbtTag SaveSection() { // Create the tags to save this section NbtCompound section = new NbtCompound("About"); section.Tags.Add(new NbtString("Name", Name)); section.Tags.Add(new NbtString("Author", Author)); section.Tags.Add(new NbtLong("CreatedOn", (long) DateTime.Now.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds)); return section; }
public Entity(NbtCompound c) { orig = c; id = (orig["id"] as NbtString).Value; SetBaseStuff(c); #if DEBUG Console.WriteLine("*** BUG: Unknown entity (ID: {0})",id); Console.WriteLine(orig); #endif }
public Item(NbtCompound c) { SetBaseStuff(c); NbtCompound i = (c["Item"] as NbtCompound); ItemID = (i["id"] as NbtShort).Value; Damage = (i["Damage"] as NbtShort).Value; Count = (i["Count"] as NbtByte).Value; Health = (c["Health"] as NbtShort).Value; Age = (c["Age"] as NbtShort).Value; B = Blocks.Get(ItemID); }
public NbtCompound Read(NbtCompound metadata) { var Data = metadata.Get<NbtCompound>("MCForge"); Logger.Log(Data["perbuild"].ToString()); if (Data != null) { perbuild = Data["perbuild"].ByteValue; pervisit = Data["pervisit"].ByteValue; metadata.Remove(Data); } return metadata; }
public static Slot FromNbt(NbtCompound compound) { var s = Slot.EmptySlot; s.Id = compound.Get<NbtShort>("id").Value; s.Metadata = compound.Get<NbtShort>("Damage").Value; s.Count = (sbyte)compound.Get<NbtByte>("Count").Value; s.Index = compound.Get<NbtByte>("Slot").Value; if (compound.Get<NbtCompound>("tag") != null) { s.Nbt = new NbtFile(); s.Nbt.RootTag = compound.Get<NbtCompound>("tag"); } return s; }
public void NbtCompoundTest() { object dummy; NbtTag test = new NbtCompound( "Derp" ); Assert.Throws<InvalidCastException>( () => dummy = test.ByteArrayValue ); Assert.Throws<InvalidCastException>( () => dummy = test.ByteValue ); Assert.Throws<InvalidCastException>( () => dummy = test.DoubleValue ); Assert.Throws<InvalidCastException>( () => dummy = test.FloatValue ); Assert.Throws<InvalidCastException>( () => dummy = test.IntArrayValue ); Assert.Throws<InvalidCastException>( () => dummy = test.IntValue ); Assert.Throws<InvalidCastException>( () => dummy = test.LongValue ); Assert.Throws<InvalidCastException>( () => dummy = test.ShortValue ); Assert.Throws<InvalidCastException>( () => dummy = test.StringValue ); }
public LivingEntity(NbtCompound c) { SetBaseStuff(c); if (!c.Has("HurtTime")) { Console.WriteLine(c); return; } lolID = (c["id"] as NbtString).Value; Health = (c["Health"] as NbtShort).Value; HurtTime = (c["HurtTime"] as NbtShort).Value; AttackTime = (c["AttackTime"] as NbtShort).Value; DeathTime = (c["DeathTime"] as NbtShort).Value; }
public static void Load(this Player player) { try { string path = Config.GetProperty("PluginDirectory", ".\\") + "\\PlayerSave\\players\\" + player.PlayerInfo.Username.ToLower() + ".dat"; NbtFile file = new NbtFile(); file.LoadFromFile(path, NbtCompression.ZLib, null); NbtCompound nbt = file.RootTag; NbtString levelName = nbt["Level"] as NbtString; Level level = player.GetServer().LevelManager.Levels.Find(obj => { return(obj.LevelName == levelName.Value); }); if (level == null) { return; } NbtList pos = nbt["Pos"] as NbtList; NbtList rotation = nbt["Rotation"] as NbtList; player.SpawnLevel(level, new PlayerLocation(pos[0].DoubleValue, pos[1].DoubleValue, pos[2].DoubleValue, 0, rotation[0].FloatValue, rotation[1].FloatValue)); player.HealthManager.Health = (int)nbt["Health"].FloatValue; //이펙트 보류 //NbtList effects = nbt["ActiveEffects"] as NbtList; //foreach (NbtTag tag in effects) //{ // NbtCompound effectNbt = tag as NbtCompound; //} player.HungerManager.Hunger = nbt["foodlevel"].IntValue; player.HungerManager.Saturation = nbt["foodSaturationLevel"].FloatValue; player.HungerManager.Exhaustion = nbt["foodExhaustionLevel"].FloatValue; player.Experience = nbt["XpP"].FloatValue; player.ExperienceLevel = nbt["XpLevel"].IntValue; NbtList inventoryList = nbt["Inventory"] as NbtList; for (int i = 0; i < inventoryList.Count; i++) { NbtCompound invNbt = inventoryList[i] as NbtCompound; byte slot = invNbt["Slot"].ByteValue; if (slot < 100) { if (player.Inventory.Slots.Count > i) { player.Inventory.SetInventorySlot(slot, ItemFactory.GetItem(invNbt["id"].ShortValue, invNbt["Damage"].ShortValue, invNbt["Count"].ByteValue)); } } else { switch (slot) { case 100: player.Inventory.Helmet = ItemFactory.GetItem(invNbt["id"].ShortValue, invNbt["Damage"].ShortValue, invNbt["Count"].ByteValue); break; case 101: player.Inventory.Chest = ItemFactory.GetItem(invNbt["id"].ShortValue, invNbt["Damage"].ShortValue, invNbt["Count"].ByteValue); break; case 102: player.Inventory.Leggings = ItemFactory.GetItem(invNbt["id"].ShortValue, invNbt["Damage"].ShortValue, invNbt["Count"].ByteValue); break; case 103: player.Inventory.Boots = ItemFactory.GetItem(invNbt["id"].ShortValue, invNbt["Damage"].ShortValue, invNbt["Count"].ByteValue); break; } } } player.Inventory.InHandSlot = nbt["SelectedInventorySlot"].IntValue; player.SetGameMode((GameMode)nbt["playerGameType"].IntValue); } catch (Exception e) { ConsoleColor col = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); Console.ForegroundColor = col; } }
public NbtCompound writeToNbt(NbtCompound tag, bool deleteEntities) { tag.Add(new NbtByte("hasDoneGen2", this.hasDoneGen2 ? (byte)1 : (byte)0)); byte[] blockBytes = new byte[Chunk.BLOCK_COUNT]; int i, x, y, z; for (i = 0; i < Chunk.BLOCK_COUNT; i++) { blockBytes[i] = (byte)this.blocks[i].id; } tag.Add(new NbtByteArray("blocks", blockBytes)); tag.Add(new NbtByteArray("meta", this.metaData)); tag.Add(new NbtByteArray("light", this.lightLevel)); // Tile Entites. NbtList list = new NbtList("tileEntities", NbtTagType.Compound); foreach (TileEntityBase te in this.tileEntityDict.Values) { list.Add(te.writeToNbt(new NbtCompound())); } tag.Add(list); // Scheduled ticks. list = new NbtList("scheduledTicks", NbtTagType.Compound); ScheduledTick tick; for (i = 0; i < this.scheduledTicks.Count; i++) { tick = this.scheduledTicks[i]; list.Add(this.scheduledTicks[i].writeToNbt()); } tag.Add(list); // Entites. Entity entity; List <Entity> entitiesInChunk = new List <Entity>(); for (i = this.world.entityList.Count - 1; i >= 0; i--) { entity = this.world.entityList[i]; if (!(entity is EntityPlayer)) { x = MathHelper.floor((int)entity.transform.position.x / (float)Chunk.SIZE); y = MathHelper.floor((int)entity.transform.position.y / (float)Chunk.SIZE); z = MathHelper.floor((int)entity.transform.position.z / (float)Chunk.SIZE); if (x == this.chunkPos.x && y == this.chunkPos.y && z == this.chunkPos.z) { world.entityList.Remove(entity); entitiesInChunk.Add(entity); } } } NbtList list1 = new NbtList("entities", NbtTagType.Compound); for (i = 0; i < entitiesInChunk.Count; i++) { entity = entitiesInChunk[i]; list1.Add(entity.writeToNbt(new NbtCompound())); if (deleteEntities) { GameObject.Destroy(entity.gameObject); } } tag.Add(list1); return(tag); }
public override void SetCompound(NbtCompound compound) { _compound = compound; }
public void SetBlockEntity(Vector3 coordinates, NbtCompound nbt) { IsDirty = true; TileEntities[coordinates] = nbt; }
private static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk, int yoffset) { var nbt = new NbtFile(); NbtCompound levelTag = new NbtCompound("Level"); nbt.RootTag.Add(levelTag); levelTag.Add(new NbtInt("xPos", chunk.x)); levelTag.Add(new NbtInt("zPos", chunk.z)); levelTag.Add(new NbtByteArray("Biomes", chunk.biomeId)); NbtList sectionsTag = new NbtList("Sections"); levelTag.Add(sectionsTag); for (int i = 0; i < 8; i++) { NbtCompound sectionTag = new NbtCompound(); sectionsTag.Add(sectionTag); sectionTag.Add(new NbtByte("Y", (byte)i)); int sy = i * 16; byte[] blocks = new byte[4096]; byte[] data = new byte[2048]; byte[] blockLight = new byte[2048]; byte[] skyLight = new byte[2048]; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int yi = sy + y; if (yi < 0 || yi >= 256) { continue; // ? } int anvilIndex = (y + yoffset) * 16 * 16 + z * 16 + x; byte blockId = chunk.GetBlock(x, yi, z); // PE to Anvil friendly converstion if (blockId == 5) { blockId = 125; } else if (blockId == 158) { blockId = 126; } else if (blockId == 50) { blockId = 75; } else if (blockId == 50) { blockId = 76; } else if (blockId == 89) { blockId = 123; } else if (blockId == 89) { blockId = 124; } else if (blockId == 73) { blockId = 152; } blocks[anvilIndex] = blockId; SetNibble4(data, anvilIndex, chunk.GetMetadata(x, yi, z)); SetNibble4(blockLight, anvilIndex, chunk.GetBlocklight(x, yi, z)); SetNibble4(skyLight, anvilIndex, chunk.GetSkylight(x, yi, z)); } } } sectionTag.Add(new NbtByteArray("Blocks", blocks)); sectionTag.Add(new NbtByteArray("Data", data)); sectionTag.Add(new NbtByteArray("BlockLight", blockLight)); sectionTag.Add(new NbtByteArray("SkyLight", skyLight)); } // TODO: Save entities NbtList entitiesTag = new NbtList("Entities", NbtTagType.Compound); levelTag.Add(entitiesTag); NbtList blockEntitiesTag = new NbtList("TileEntities", NbtTagType.Compound); levelTag.Add(blockEntitiesTag); foreach (NbtCompound blockEntityNbt in chunk.BlockEntities.Values) { NbtCompound nbtClone = (NbtCompound)blockEntityNbt.Clone(); nbtClone.Name = null; blockEntitiesTag.Add(nbtClone); } levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound)); return(nbt); }
public void AddingAndRemoving() { var foo = new NbtInt("Foo"); var test = new NbtCompound { foo }; // adding duplicate object Assert.Throws <ArgumentException>(() => test.Add(foo)); // adding duplicate name Assert.Throws <ArgumentException>(() => test.Add(new NbtByte("Foo"))); // adding unnamed tag Assert.Throws <ArgumentException>(() => test.Add(new NbtInt())); // adding null Assert.Throws <ArgumentNullException>(() => test.Add(null)); // adding tag to self Assert.Throws <ArgumentException>(() => test.Add(test)); // contains existing name/object Assert.IsTrue(test.Contains("Foo")); Assert.IsTrue(test.Contains(foo)); Assert.Throws <ArgumentNullException>(() => test.Contains((string)null)); Assert.Throws <ArgumentNullException>(() => test.Contains((NbtTag)null)); // contains non-existent name Assert.IsFalse(test.Contains("Bar")); // contains existing name / different object Assert.IsFalse(test.Contains(new NbtInt("Foo"))); // removing non-existent name Assert.Throws <ArgumentNullException>(() => test.Remove((string)null)); Assert.IsFalse(test.Remove("Bar")); // removing existing name Assert.IsTrue(test.Remove("Foo")); // removing non-existent name Assert.IsFalse(test.Remove("Foo")); // re-adding object test.Add(foo); // removing existing object Assert.Throws <ArgumentNullException>(() => test.Remove((NbtTag)null)); Assert.IsTrue(test.Remove(foo)); Assert.IsFalse(test.Remove(foo)); // clearing an empty NbtCompound Assert.AreEqual(0, test.Count); test.Clear(); // re-adding after clearing test.Add(foo); Assert.AreEqual(1, test.Count); // clearing a non-empty NbtCompound test.Clear(); Assert.AreEqual(0, test.Count); }
public override void readFromNbt(NbtCompound tag) { base.readFromNbt(tag); this.heldResources = tag.getInt("builderResources"); }
public static void setTag(this NbtCompound tag, string name, long value) { tag.Add(new NbtLong(name, value)); }
public static void setTag(this NbtCompound tag, string name, NbtList value) { value.Name = name; tag.Add(value); }
public static void setTag(this NbtCompound tag, string name, int[] value) { tag.Add(new NbtIntArray(name, value)); }
public static void setTag(this NbtCompound tag, string name, float value) { tag.Add(new NbtFloat(name, value)); }
//public static void setTag(this NbtCompound tag, string name, NbtCompound value) { // tag.Add(new NbtCompound(name, value)); //} public static void setTag(this NbtCompound tag, string name, double value) { tag.Add(new NbtDouble(name, value)); }
public static void setTag(this NbtCompound tag, string name, byte[] value) { tag.Add(new NbtByteArray(name, value)); }
public virtual NbtCompound writeToNbt(NbtCompound tag) { return(tag); }
public virtual void readFromNbt(NbtCompound tag) { }
public static void setTag(this NbtCompound tag, string name, short value) { tag.Add(new NbtShort(name, value)); }
public override void writeToNbt(NbtCompound tag) { base.writeToNbt(tag); tag.setTag("builderResources", this.heldResources); }
public static void setTag(this NbtCompound tag, string name, Guid value) { tag.Add(new NbtString(name, value.ToString())); }
public void GettersAndSetters() { // construct a document for us to test. var nestedChild = new NbtCompound("NestedChild"); var nestedInt = new NbtInt(1); var nestedChildList = new NbtList("NestedChildList") { nestedInt }; var child = new NbtCompound("Child") { nestedChild, nestedChildList }; var childList = new NbtList("ChildList") { new NbtInt(1) }; var parent = new NbtCompound("Parent") { child, childList }; // Accessing nested compound tags using indexers Assert.AreEqual(nestedChild, parent["Child"]["NestedChild"]); Assert.AreEqual(nestedChildList, parent["Child"]["NestedChildList"]); Assert.AreEqual(nestedInt, parent["Child"]["NestedChildList"][0]); // Accessing nested compound tags using Get and Get<T> Assert.Throws <ArgumentNullException>(() => parent.Get <NbtCompound>(null)); Assert.IsNull(parent.Get <NbtCompound>("NonExistingChild")); Assert.AreEqual(nestedChild, parent.Get <NbtCompound>("Child").Get <NbtCompound>("NestedChild")); Assert.AreEqual(nestedChildList, parent.Get <NbtCompound>("Child").Get <NbtList>("NestedChildList")); Assert.AreEqual(nestedInt, parent.Get <NbtCompound>("Child").Get <NbtList>("NestedChildList")[0]); Assert.Throws <ArgumentNullException>(() => parent.Get(null)); Assert.IsNull(parent.Get("NonExistingChild")); Assert.AreEqual(nestedChild, (parent.Get("Child") as NbtCompound).Get("NestedChild")); Assert.AreEqual(nestedChildList, (parent.Get("Child") as NbtCompound).Get("NestedChildList")); Assert.AreEqual(nestedInt, (parent.Get("Child") as NbtCompound).Get("NestedChildList")[0]); // Accessing with Get<T> and an invalid given type Assert.Throws <InvalidCastException>(() => parent.Get <NbtInt>("Child")); // Using TryGet and TryGet<T> NbtTag dummyTag; Assert.Throws <ArgumentNullException>(() => parent.TryGet(null, out dummyTag)); Assert.IsFalse(parent.TryGet("NonExistingChild", out dummyTag)); Assert.IsTrue(parent.TryGet("Child", out dummyTag)); NbtCompound dummyCompoundTag; Assert.Throws <ArgumentNullException>(() => parent.TryGet(null, out dummyCompoundTag)); Assert.IsFalse(parent.TryGet("NonExistingChild", out dummyCompoundTag)); Assert.IsTrue(parent.TryGet("Child", out dummyCompoundTag)); // Trying to use integer indexers on non-NbtList tags Assert.Throws <InvalidOperationException>(() => parent[0] = nestedInt); Assert.Throws <InvalidOperationException>(() => nestedInt[0] = nestedInt); // Trying to use string indexers on non-NbtCompound tags Assert.Throws <InvalidOperationException>(() => childList["test"] = nestedInt); Assert.Throws <InvalidOperationException>(() => nestedInt["test"] = nestedInt); // Trying to get a non-existent element by name Assert.IsNull(parent.Get <NbtTag>("NonExistentTag")); Assert.IsNull(parent["NonExistentTag"]); // Null indices on NbtCompound Assert.Throws <ArgumentNullException>(() => parent.Get <NbtTag>(null)); Assert.Throws <ArgumentNullException>(() => parent[null] = new NbtInt(1)); Assert.Throws <ArgumentNullException>(() => nestedInt = (NbtInt)parent[null]); // Out-of-range indices on NbtList Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = (NbtInt)childList[-1]); Assert.Throws <ArgumentOutOfRangeException>(() => childList[-1] = new NbtInt(1)); Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = childList.Get <NbtInt>(-1)); Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = (NbtInt)childList[childList.Count]); Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = childList.Get <NbtInt>(childList.Count)); // Using setter correctly parent["NewChild"] = new NbtByte("NewChild"); // Using setter incorrectly object dummyObject; Assert.Throws <ArgumentNullException>(() => parent["Child"] = null); Assert.NotNull(parent["Child"]); Assert.Throws <ArgumentException>(() => parent["Child"] = new NbtByte("NotChild")); Assert.Throws <InvalidOperationException>(() => dummyObject = parent[0]); Assert.Throws <InvalidOperationException>(() => parent[0] = new NbtByte("NewerChild")); // Try adding tag to self var selfTest = new NbtCompound("SelfTest"); Assert.Throws <ArgumentException>(() => selfTest["SelfTest"] = selfTest); // Try adding a tag that already has a parent Assert.Throws <ArgumentException>(() => selfTest[child.Name] = child); }
public static void AssertNbtBigFile(NbtFile file) { // See TestFiles/bigtest.nbt.txt to see the expected format Assert.IsType <NbtCompound>(file.RootTag); NbtCompound root = file.RootTag; Assert.Equal("Level", root.Name); Assert.Equal(12, root.Count); Assert.IsType <NbtLong>(root["longTest"]); NbtTag node = root["longTest"]; Assert.Equal("longTest", node.Name); Assert.Equal(9223372036854775807, ((NbtLong)node).Value); Assert.IsType <NbtShort>(root["shortTest"]); node = root["shortTest"]; Assert.Equal("shortTest", node.Name); Assert.Equal(32767, ((NbtShort)node).Value); Assert.IsType <NbtString>(root["stringTest"]); node = root["stringTest"]; Assert.Equal("stringTest", node.Name); Assert.Equal("HELLO WORLD THIS IS A TEST STRING ÅÄÖ!", ((NbtString)node).Value); Assert.IsType <NbtFloat>(root["floatTest"]); node = root["floatTest"]; Assert.Equal("floatTest", node.Name); Assert.Equal(0.49823147f, ((NbtFloat)node).Value); Assert.IsType <NbtInt>(root["intTest"]); node = root["intTest"]; Assert.Equal("intTest", node.Name); Assert.Equal(2147483647, ((NbtInt)node).Value); Assert.IsType <NbtCompound>(root["nested compound test"]); node = root["nested compound test"]; Assert.Equal("nested compound test", node.Name); Assert.Equal(2, ((NbtCompound)node).Count); // First nested test Assert.IsType <NbtCompound>(node["ham"]); var subNode = (NbtCompound)node["ham"]; Assert.Equal("ham", subNode.Name); Assert.Equal(2, subNode.Count); // Checking sub node values Assert.IsType <NbtString>(subNode["name"]); Assert.Equal("name", subNode["name"].Name); Assert.Equal("Hampus", ((NbtString)subNode["name"]).Value); Assert.IsType <NbtFloat>(subNode["value"]); Assert.Equal("value", subNode["value"].Name); Assert.Equal(0.75, ((NbtFloat)subNode["value"]).Value); // End sub node // Second nested test Assert.IsType <NbtCompound>(node["egg"]); subNode = (NbtCompound)node["egg"]; Assert.Equal("egg", subNode.Name); Assert.Equal(2, subNode.Count); // Checking sub node values Assert.IsType <NbtString>(subNode["name"]); Assert.Equal("name", subNode["name"].Name); Assert.Equal("Eggbert", ((NbtString)subNode["name"]).Value); Assert.IsType <NbtFloat>(subNode["value"]); Assert.Equal("value", subNode["value"].Name); Assert.Equal(0.5, ((NbtFloat)subNode["value"]).Value); // End sub node Assert.IsType <NbtList>(root["listTest (long)"]); node = root["listTest (long)"]; Assert.Equal("listTest (long)", node.Name); Assert.Equal(5, ((NbtList)node).Count); // The values should be: 11, 12, 13, 14, 15 for (int nodeIndex = 0; nodeIndex < ((NbtList)node).Count; nodeIndex++) { Assert.IsType <NbtLong>(node[nodeIndex]); Assert.Equal(null, node[nodeIndex].Name); Assert.Equal(nodeIndex + 11, ((NbtLong)node[nodeIndex]).Value); } Assert.IsType <NbtList>(root["listTest (compound)"]); node = root["listTest (compound)"]; Assert.Equal("listTest (compound)", node.Name); Assert.Equal(2, ((NbtList)node).Count); // First Sub Node Assert.IsType <NbtCompound>(node[0]); subNode = (NbtCompound)node[0]; // First node in sub node Assert.IsType <NbtString>(subNode["name"]); Assert.Equal("name", subNode["name"].Name); Assert.Equal("Compound tag #0", ((NbtString)subNode["name"]).Value); // Second node in sub node Assert.IsType <NbtLong>(subNode["created-on"]); Assert.Equal("created-on", subNode["created-on"].Name); Assert.Equal(1264099775885, ((NbtLong)subNode["created-on"]).Value); // Second Sub Node Assert.IsType <NbtCompound>(node[1]); subNode = (NbtCompound)node[1]; // First node in sub node Assert.IsType <NbtString>(subNode["name"]); Assert.Equal("name", subNode["name"].Name); Assert.Equal("Compound tag #1", ((NbtString)subNode["name"]).Value); // Second node in sub node Assert.IsType <NbtLong>(subNode["created-on"]); Assert.Equal("created-on", subNode["created-on"].Name); Assert.Equal(1264099775885, ((NbtLong)subNode["created-on"]).Value); Assert.IsType <NbtByte>(root["byteTest"]); node = root["byteTest"]; Assert.Equal("byteTest", node.Name); Assert.Equal(127, ((NbtByte)node).Value); const string byteArrayName = "byteArrayTest (the first 1000 values of (n*n*255+n*7)%100, starting with n=0 (0, 62, 34, 16, 8, ...))"; Assert.IsType <NbtByteArray>(root[byteArrayName]); node = root[byteArrayName]; Assert.Equal(byteArrayName, node.Name); Assert.Equal(1000, ((NbtByteArray)node).Value.Length); // Values are: the first 1000 values of (n*n*255+n*7)%100, starting with n=0 (0, 62, 34, 16, 8, ...) for (int n = 0; n < 1000; n++) { Assert.Equal((n * n * 255 + n * 7) % 100, ((NbtByteArray)node)[n]); } Assert.IsType <NbtDouble>(root["doubleTest"]); node = root["doubleTest"]; Assert.Equal("doubleTest", node.Name); Assert.Equal(0.4931287132182315, ((NbtDouble)node).Value); Assert.IsType <NbtIntArray>(root["intArrayTest"]); var intArrayTag = root.Get <NbtIntArray>("intArrayTest"); Assert.NotNull(intArrayTag); var rand = new Random(0); for (int i = 0; i < 10; i++) { Assert.Equal(rand.Next(), intArrayTag.Value[i]); } }
public static void SaveOfflinePlayerData(this MiNetServer server, string name, NbtCompound nbtTag, bool async = false) { NbtFile nbt = new NbtFile(nbtTag); nbt.BigEndian = true; ParameterizedThreadStart threadStart = new ParameterizedThreadStart(obj => { try { string path = Config.GetProperty("PluginDirectory", ".\\") + "\\PlayerSave\\players\\"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } ((NbtFile)((object[])obj)[0]).SaveToFile(path + ((object[])obj)[1].ToString().ToLower() + ".dat", NbtCompression.ZLib); } catch (Exception e) { ConsoleColor col = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); Console.ForegroundColor = col; } }); Thread thread = new Thread(threadStart); if (async) { thread.Start(new object[] { nbt, name }); } else { threadStart(new object[] { nbt, name }); } }
public static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk) { var nbt = new NbtFile(); NbtCompound levelTag = new NbtCompound("Level"); nbt.RootTag.Add(levelTag); levelTag.Add(new NbtByte("MCPE BID", 1)); // Indicate that the chunks contain PE block ID's. levelTag.Add(new NbtInt("xPos", chunk.x)); levelTag.Add(new NbtInt("zPos", chunk.z)); levelTag.Add(new NbtByteArray("Biomes", chunk.biomeId)); NbtList sectionsTag = new NbtList("Sections", NbtTagType.Compound); levelTag.Add(sectionsTag); for (int i = 0; i < 16; i++) { var section = chunk.chunks[i]; if (section.IsAllAir()) { continue; } NbtCompound sectionTag = new NbtCompound(); sectionsTag.Add(sectionTag); sectionTag.Add(new NbtByte("Y", (byte)i)); byte[] blocks = new byte[4096]; byte[] data = new byte[2048]; byte[] blockLight = new byte[2048]; byte[] skyLight = new byte[2048]; { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int anvilIndex = y * 16 * 16 + z * 16 + x; byte blockId = section.GetBlock(x, y, z); blocks[anvilIndex] = blockId; SetNibble4(data, anvilIndex, section.GetMetadata(x, y, z)); SetNibble4(blockLight, anvilIndex, section.GetBlocklight(x, y, z)); SetNibble4(skyLight, anvilIndex, section.GetSkylight(x, y, z)); } } } } sectionTag.Add(new NbtByteArray("Blocks", blocks)); sectionTag.Add(new NbtByteArray("Data", data)); sectionTag.Add(new NbtByteArray("BlockLight", blockLight)); sectionTag.Add(new NbtByteArray("SkyLight", skyLight)); } int[] heights = new int[256]; for (int h = 0; h < heights.Length; h++) { heights[h] = chunk.height[h]; } levelTag.Add(new NbtIntArray("HeightMap", heights)); // TODO: Save entities NbtList entitiesTag = new NbtList("Entities", NbtTagType.Compound); levelTag.Add(entitiesTag); NbtList blockEntitiesTag = new NbtList("TileEntities", NbtTagType.Compound); foreach (NbtCompound blockEntityNbt in chunk.BlockEntities.Values) { NbtCompound nbtClone = (NbtCompound)blockEntityNbt.Clone(); nbtClone.Name = null; blockEntitiesTag.Add(nbtClone); } levelTag.Add(blockEntitiesTag); levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound)); return(nbt); }
private void HandleChunk(bool cacheEnabled, uint subChunkCount, byte[] chunkData, int cx, int cz, Action <ChunkColumn> callback) { if (cacheEnabled) { Log.Warn($"Unsupported cache enabled!"); } bool gotLight = false; try { using (MemoryStream stream = new MemoryStream(chunkData)) { NbtBinaryReader defStream = new NbtBinaryReader(stream, true); //int count = defStream.ReadByte(); if (subChunkCount < 1) { Log.Warn("Nothing to read"); return; } ChunkColumn chunkColumn = new ChunkColumn(); chunkColumn.IsDirty = true; chunkColumn.X = cx; chunkColumn.Z = cz; for (int s = 0; s < subChunkCount; s++) { var section = chunkColumn.Sections[s] as ChunkSection; int version = defStream.ReadByte(); if (version == 1 || version == 8) { int storageSize = defStream.ReadByte(); if (section == null) { section = new ChunkSection(chunkColumn, s, true, 2); } for (int storage = 0; storage < storageSize; storage++) { int paletteAndFlag = defStream.ReadByte(); bool isRuntime = (paletteAndFlag & 1) != 0; int bitsPerBlock = paletteAndFlag >> 1; int blocksPerWord = (int)Math.Floor(32f / bitsPerBlock); int wordCount = (int)Math.Ceiling(4096.0f / blocksPerWord); uint[] words = new uint[wordCount]; for (int w = 0; w < wordCount; w++) { int word = defStream.ReadInt32(); words[w] = SwapBytes((uint)word); } uint[] pallete = new uint[0]; if (isRuntime) { int palleteSize = VarInt.ReadSInt32(stream); pallete = new uint[palleteSize]; for (int pi = 0; pi < pallete.Length; pi++) { var ui = (uint)VarInt.ReadSInt32(stream); pallete[pi] = ui; } if (palleteSize == 0) { Log.Warn($"Pallete size is 0"); continue; } } int position = 0; for (int w = 0; w < wordCount; w++) { uint word = words[w]; for (int block = 0; block < blocksPerWord; block++) { if (position >= 4096) { break; // padding bytes } uint state = (uint)((word >> ((position % blocksPerWord) * bitsPerBlock)) & ((1 << bitsPerBlock) - 1)); int x = (position >> 8) & 0xF; int y = position & 0xF; int z = (position >> 4) & 0xF; if (state >= pallete.Length) { continue; } BlockState translated = GetBlockState(pallete[state]); if (translated != null) { if (translated.Block is Water) { string a = ""; } section.Set(storage, x, y, z, translated); } position++; } if (position >= 4096) { break; } } } } else { if (section == null) { section = new ChunkSection(chunkColumn, s, true, 1); } #region OldFormat byte[] blockIds = new byte[4096]; defStream.Read(blockIds, 0, blockIds.Length); NibbleArray data = new NibbleArray(4096); defStream.Read(data.Data, 0, data.Data.Length); for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int idx = (x << 8) + (z << 4) + y; var id = blockIds[idx]; var meta = data[idx]; var ruid = BlockFactory.GetBlockStateID(id, meta); BlockState result = null; if (!_convertedStates.TryGetValue( ruid, out result)) { if (id == 124 || id == 123) { result = BlockFactory.GetBlockState("minecraft:redstone_lamp"); if (id == 124) { result = result.WithProperty("lit", "true"); } } else if (id > 0 && result == null) { var reverseMap = MiNET.Worlds.AnvilWorldProvider.Convert.FirstOrDefault( map => map.Value.Item1 == id); if (reverseMap.Value != null) { id = (byte)reverseMap.Key; } var res = BlockFactory.GetBlockStateID(id, meta); if (AnvilWorldProvider.BlockStateMapper.TryGetValue(res, out var res2)) { var t = BlockFactory.GetBlockState(res2); t = TranslateBlockState(t, id, meta); result = t; } else { Log.Info($"Did not find anvil statemap: {result.Name}"); result = TranslateBlockState( BlockFactory.GetBlockState(res), id, meta); } } if (result == null) { var results = BlockFactory.RuntimeIdTable.Where(xx => xx.Id == id) .ToArray(); if (results.Length > 0) { var first = results.FirstOrDefault(xx => xx.Data == meta); if (first == default) { first = results[0]; } result = TranslateBlockState( BlockFactory.GetBlockState((uint)first.RuntimeId), id, meta); } } if (result == null) { result = new BlockState() { Name = $"{id}:{meta.ToString()}", Model = BlockFactory.UnknownBlockModel, Block = new Block(0) { } }; Log.Info($"Unknown block: {id}:{meta}"); } if (result != null) { _convertedStates.TryAdd(ruid, result); } } if (result != null) { section.Set(x, y, z, result); } else { Log.Info($"Unknown block: {id}:{meta}"); } } } } #endregion } if (UseAlexChunks) { // Log.Info($"Alex chunk!"); var rawSky = new API.Utils.NibbleArray(4096); defStream.Read(rawSky.Data, 0, rawSky.Data.Length); var rawBlock = new API.Utils.NibbleArray(4096); defStream.Read(rawBlock.Data, 0, rawBlock.Data.Length); for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { var peIndex = (x * 256) + (z * 16) + y; var sky = rawSky[peIndex]; var block = rawBlock[peIndex]; var idx = y << 8 | z << 4 | x; section.SkyLight[idx] = sky; section.BlockLight[idx] = block; } } } gotLight = true; } section.RemoveInvalidBlocks(); section.IsDirty = true; //Make sure the section is saved. chunkColumn.Sections[s] = section; } /* byte[] ba = new byte[512]; * if (defStream.Read(ba, 0, 256 * 2) != 256 * 2) Log.Error($"Out of data height"); * * Buffer.BlockCopy(ba, 0, chunkColumn.Height, 0, 512);*/ int[] biomeIds = new int[256]; for (int i = 0; i < biomeIds.Length; i++) { biomeIds[i] = defStream.ReadByte(); } chunkColumn.BiomeId = biomeIds; if (stream.Position >= stream.Length - 1) { callback?.Invoke(chunkColumn); return; } int borderBlock = VarInt.ReadSInt32(stream); if (borderBlock > 0) { byte[] buf = new byte[borderBlock]; int len = defStream.Read(buf, 0, borderBlock); } if (stream.Position < stream.Length - 1) { int loop = 0; while (stream.Position < stream.Length - 1) { try { NbtFile file = new NbtFile() { BigEndian = false, UseVarInt = true }; file.LoadFromStream(stream, NbtCompression.None); if (file.RootTag.Name == "alex") { NbtCompound alexCompound = (NbtCompound)file.RootTag; for (int ci = 0; ci < subChunkCount; ci++) { var section = (ChunkSection)chunkColumn.Sections[ci]; var rawSky = new API.Utils.NibbleArray(4096); if (alexCompound.TryGet($"skylight-{ci}", out NbtByteArray skyData)) { rawSky.Data = skyData.Value; } //defStream.Read(rawSky.Data, 0, rawSky.Data.Length); var rawBlock = new API.Utils.NibbleArray(4096); if (alexCompound.TryGet($"blocklight-{ci}", out NbtByteArray blockData)) { rawBlock.Data = blockData.Value; } for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { var peIndex = (x * 256) + (z * 16) + y; var sky = rawSky[peIndex]; var block = rawBlock[peIndex]; var idx = y << 8 | z << 4 | x; section.SkyLight[idx] = sky; section.BlockLight[idx] = block; } } } chunkColumn.Sections[ci] = section; } gotLight = true; } if (stream.Position < stream.Length - 1) { // pre = stream.ReadByte(); } } catch (Exception ex) { // Log.Warn(ex, $"Reading chunk extra data (Loop={loop})"); } loop++; } } if (stream.Position < stream.Length - 1) { Log.Warn( $"Still have data to read\n{Packet.HexDump(defStream.ReadBytes((int) (stream.Length - stream.Position)))}"); } if (gotLight) { chunkColumn.SkyLightDirty = false; chunkColumn.BlockLightDirty = false; } chunkColumn.CalculateHeight(!gotLight && ClientSideLighting); //Done processing this chunk, send to world callback?.Invoke(chunkColumn); } } catch (Exception ex) { Log.Error($"Exception in chunk loading: {ex.ToString()}"); } finally { } }
public static ChunkColumn GetChunk(ChunkCoordinates coordinates, string basePath, IWorldProvider generator, int yoffset) { int width = 32; int depth = 32; int rx = coordinates.X >> 5; int rz = coordinates.Z >> 5; string filePath = Path.Combine(basePath, string.Format(@"region{2}r.{0}.{1}.mca", rx, rz, Path.DirectorySeparatorChar)); if (!File.Exists(filePath)) { return(generator?.GenerateChunkColumn(coordinates)); //return new ChunkColumn //{ // x = coordinates.X, // z = coordinates.Z, //}; } using (var regionFile = File.OpenRead(filePath)) { byte[] buffer = new byte[8192]; regionFile.Read(buffer, 0, 8192); int xi = (coordinates.X % width); if (xi < 0) { xi += 32; } int zi = (coordinates.Z % depth); if (zi < 0) { zi += 32; } int tableOffset = (xi + zi * width) * 4; regionFile.Seek(tableOffset, SeekOrigin.Begin); byte[] offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); int offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; int length = regionFile.ReadByte(); if (offset == 0 || length == 0) { return(generator?.GenerateChunkColumn(coordinates)); //return new ChunkColumn //{ // x = coordinates.X, // z = coordinates.Z, //}; } regionFile.Seek(offset, SeekOrigin.Begin); byte[] waste = new byte[4]; regionFile.Read(waste, 0, 4); int compressionMode = regionFile.ReadByte(); var nbt = new NbtFile(); nbt.LoadFromStream(regionFile, NbtCompression.ZLib); NbtTag dataTag = nbt.RootTag["Level"]; NbtList sections = dataTag["Sections"] as NbtList; ChunkColumn chunk = new ChunkColumn { x = coordinates.X, z = coordinates.Z, biomeId = dataTag["Biomes"].ByteArrayValue, isAllAir = true }; if (chunk.biomeId.Length > 256) { throw new Exception(); } // This will turn into a full chunk column foreach (NbtTag sectionTag in sections) { int sy = sectionTag["Y"].ByteValue * 16; byte[] blocks = sectionTag["Blocks"].ByteArrayValue; byte[] data = sectionTag["Data"].ByteArrayValue; NbtTag addTag = sectionTag["Add"]; byte[] adddata = new byte[2048]; if (addTag != null) { adddata = addTag.ByteArrayValue; } byte[] blockLight = sectionTag["BlockLight"].ByteArrayValue; byte[] skyLight = sectionTag["SkyLight"].ByteArrayValue; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int yi = sy + y - yoffset; if (yi < 0 || yi >= 128) { continue; } int anvilIndex = y * 16 * 16 + z * 16 + x; int blockId = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8); // Anvil to PE friendly converstion Func <int, byte, byte> dataConverter = (i, b) => b; // Default no-op converter if (Convert.ContainsKey(blockId)) { dataConverter = Convert[blockId].Item2; blockId = Convert[blockId].Item1; } chunk.isAllAir = chunk.isAllAir && blockId == 0; if (blockId > 255) { blockId = 41; } //if (yi == 127 && blockId != 0) blockId = 30; if (yi == 0 && (blockId == 8 || blockId == 9)) { blockId = 7; } chunk.SetBlock(x, yi, z, (byte)blockId); byte metadata = Nibble4(data, anvilIndex); metadata = dataConverter(blockId, metadata); chunk.SetMetadata(x, yi, z, metadata); chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex)); chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex)); var block = BlockFactory.GetBlockById(chunk.GetBlock(x, yi, z)); if (block is BlockStairs || block is StoneSlab || block is WoodSlab) { chunk.SetSkylight(x, yi, z, 0xff); } if (blockId == 43 && chunk.GetMetadata(x, yi, z) == 7) { chunk.SetMetadata(x, yi, z, 6); } else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 7) { chunk.SetMetadata(x, yi, z, 6); } else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 15) { chunk.SetMetadata(x, yi, z, 14); } else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 1) { // Dirt Course => (Grass Path) chunk.SetBlock(x, yi, z, 198); chunk.SetMetadata(x, yi, z, 0); } else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 2) { // Dirt Podzol => (Podzol) chunk.SetBlock(x, yi, z, 243); chunk.SetMetadata(x, yi, z, 0); } } } } } NbtList entities = dataTag["Entities"] as NbtList; NbtList blockEntities = dataTag["TileEntities"] as NbtList; if (blockEntities != null) { foreach (var nbtTag in blockEntities) { var blockEntityTag = (NbtCompound)nbtTag.Clone(); string entityId = blockEntityTag["id"].StringValue; int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue - yoffset; int z = blockEntityTag["z"].IntValue; blockEntityTag["y"] = new NbtInt("y", y); BlockEntity blockEntity = BlockEntityFactory.GetBlockEntityById(entityId); if (blockEntity != null) { blockEntityTag.Name = string.Empty; if (blockEntity is Sign) { // Remove the JSON stuff and get the text out of extra data. // TAG_String("Text2"): "{"extra":["10c a loaf!"],"text":""}" CleanSignText(blockEntityTag, "Text1"); CleanSignText(blockEntityTag, "Text2"); CleanSignText(blockEntityTag, "Text3"); CleanSignText(blockEntityTag, "Text4"); } else if (blockEntity is ChestBlockEntity) { NbtList items = (NbtList)blockEntityTag["Items"]; for (byte i = 0; i < items.Count; i++) { NbtCompound item = (NbtCompound)items[i]; item.Add(new NbtShort("OriginalDamage", item["Damage"].ShortValue)); byte metadata = (byte)(item["Damage"].ShortValue & 0xff); item.Remove("Damage"); item.Add(new NbtByte("Damage", metadata)); } } chunk.SetBlockEntity(new BlockCoordinates(x, y, z), blockEntityTag); } } } //NbtList tileTicks = dataTag["TileTicks"] as NbtList; chunk.isDirty = false; return(chunk); } }
public static void setTag(this NbtCompound tag, string name, bool value) { tag.setTag(name, value ? (byte)1 : (byte)0); }
public FallingSand(NbtCompound c) { SetBaseStuff(c); Tile = (c["Tile"] as NbtByte).Value; }
public override void readFromNbt(NbtCompound tag) { base.readFromNbt(tag); this.stack = new ItemStack(tag.Get <NbtCompound>("stack")); this.timeAlive = tag.Get <NbtFloat>("pickupDelay").FloatValue; }
public override void TileEntityLoadedForClient(BlockDescriptor descriptor, IWorld world, NbtCompound entity, IRemoteClient client) { client.QueuePacket(new UpdateSignPacket { X = descriptor.Coordinates.X, Y = (short)descriptor.Coordinates.Y, Z = descriptor.Coordinates.Z, Text = new[] { entity["Text1"].StringValue, entity["Text2"].StringValue, entity["Text3"].StringValue, entity["Text4"].StringValue } }); }
public static bool getBool(this NbtCompound tag, string name, bool defaultValue = false) { return(tag.getByte(name, defaultValue ? (byte)1 : (byte)0) == 1); }
public ChunkColumn GetChunk(ChunkCoordinates coordinates, string basePath, IWorldGenerator generator) { try { int width = 32; int depth = 32; int rx = coordinates.X >> 5; int rz = coordinates.Z >> 5; string filePath = Path.Combine(basePath, string.Format(@"region{2}r.{0}.{1}.mca", rx, rz, Path.DirectorySeparatorChar)); if (!File.Exists(filePath)) { var chunkColumn = generator?.GenerateChunkColumn(coordinates); if (chunkColumn != null) { //chunkColumn.NeedSave = true; } return(chunkColumn); } using (var regionFile = File.OpenRead(filePath)) { byte[] buffer = new byte[8192]; regionFile.Read(buffer, 0, 8192); int xi = (coordinates.X % width); if (xi < 0) { xi += 32; } int zi = (coordinates.Z % depth); if (zi < 0) { zi += 32; } int tableOffset = (xi + zi * width) * 4; regionFile.Seek(tableOffset, SeekOrigin.Begin); byte[] offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); int offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; byte[] bytes = BitConverter.GetBytes(offset >> 4); Array.Reverse(bytes); if (offset != 0 && offsetBuffer[0] != bytes[0] && offsetBuffer[1] != bytes[1] && offsetBuffer[2] != bytes[2]) { throw new Exception($"Not the same buffer\n{Package.HexDump(offsetBuffer)}\n{Package.HexDump(bytes)}"); } int length = regionFile.ReadByte(); if (offset == 0 || length == 0) { var chunkColumn = generator?.GenerateChunkColumn(coordinates); if (chunkColumn != null) { //chunkColumn.NeedSave = true; } return(chunkColumn); } regionFile.Seek(offset, SeekOrigin.Begin); byte[] waste = new byte[4]; regionFile.Read(waste, 0, 4); int compressionMode = regionFile.ReadByte(); if (compressionMode != 0x02) { throw new Exception($"CX={coordinates.X}, CZ={coordinates.Z}, NBT wrong compression. Expected 0x02, got 0x{compressionMode:X2}. " + $"Offset={offset}, length={length}\n{Package.HexDump(waste)}"); } var nbt = new NbtFile(); nbt.LoadFromStream(regionFile, NbtCompression.ZLib); NbtCompound dataTag = (NbtCompound)nbt.RootTag["Level"]; bool isPocketEdition = false; if (dataTag.Contains("MCPE BID")) { isPocketEdition = dataTag["MCPE BID"].ByteValue == 1; } NbtList sections = dataTag["Sections"] as NbtList; ChunkColumn chunk = new ChunkColumn { x = coordinates.X, z = coordinates.Z, biomeId = dataTag["Biomes"].ByteArrayValue, isAllAir = true }; if (chunk.biomeId.Length > 256) { throw new Exception(); } NbtTag heights = dataTag["HeightMap"] as NbtIntArray; if (heights != null) { int[] intHeights = heights.IntArrayValue; for (int i = 0; i < 256; i++) { chunk.height[i] = (short)intHeights[i]; } } // This will turn into a full chunk column foreach (NbtTag sectionTag in sections) { ReadSection(sectionTag, chunk, !isPocketEdition); } NbtList entities = dataTag["Entities"] as NbtList; NbtList blockEntities = dataTag["TileEntities"] as NbtList; if (blockEntities != null) { foreach (var nbtTag in blockEntities) { var blockEntityTag = (NbtCompound)nbtTag.Clone(); string entityId = blockEntityTag["id"].StringValue; int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue; int z = blockEntityTag["z"].IntValue; if (entityId.StartsWith("minecraft:")) { var id = entityId.Split(':')[1]; entityId = id.First().ToString().ToUpper() + id.Substring(1); blockEntityTag["id"] = new NbtString("id", entityId); } BlockEntity blockEntity = BlockEntityFactory.GetBlockEntityById(entityId); if (blockEntity != null) { blockEntityTag.Name = string.Empty; if (blockEntity is Sign) { // Remove the JSON stuff and get the text out of extra data. // TAG_String("Text2"): "{"extra":["10c a loaf!"],"text":""}" CleanSignText(blockEntityTag, "Text1"); CleanSignText(blockEntityTag, "Text2"); CleanSignText(blockEntityTag, "Text3"); CleanSignText(blockEntityTag, "Text4"); } else if (blockEntity is ChestBlockEntity) { NbtList items = (NbtList)blockEntityTag["Items"]; if (items != null) { //for (byte i = 0; i < items.Count; i++) //{ // NbtCompound item = (NbtCompound) items[i]; // item.Add(new NbtShort("OriginalDamage", item["Damage"].ShortValue)); // byte metadata = (byte) (item["Damage"].ShortValue & 0xff); // item.Remove("Damage"); // item.Add(new NbtByte("Damage", metadata)); //} } } chunk.SetBlockEntity(new BlockCoordinates(x, y, z), blockEntityTag); } else { if (Log.IsDebugEnabled) { Log.Debug($"Loaded unknown block entity: {blockEntityTag}"); } } } } //NbtList tileTicks = dataTag["TileTicks"] as NbtList; chunk.RecalcHeight(); chunk.isDirty = false; chunk.NeedSave = false; return(chunk); } } catch (Exception e) { Log.Error($"Loading chunk {coordinates}", e); var chunkColumn = generator?.GenerateChunkColumn(coordinates); if (chunkColumn != null) { //chunkColumn.NeedSave = true; } return(chunkColumn); } }