private void ReadBiomesFromNBT(NBTContent nbt) { if (nbt.contents.Contains("Biomes")) { var biomeArray = nbt.contents.Get <int[]>("Biomes"); //Read topmost section, to avoid future cave biomes underground int offset = biomeArray.Length - 16; for (int x = 0; x < 4; x++) { for (int z = 0; z < 4; z++) { var value = (byte)biomeArray[offset + z * 4 + x]; for (int x1 = 0; x1 < 4; x1++) { for (int z1 = 0; z1 < 4; z1++) { biomes[x * 4 + x1, z * 4 + z1] = (BiomeID)value; } } } } } else { //Default to plains biome for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { biomes[x, z] = BiomeID.plains; } } } }
public void WriteWorldSave(string path, int playerPosX, int playerPosZ) { Directory.CreateDirectory(path); int y = GetRegionAt(playerPosX, playerPosZ).GetChunk(playerPosX % 512, playerPosZ % 512, false).GetHighestBlock(playerPosX % 16, playerPosZ % 16); levelDat = CreateLevelDAT(playerPosX, y + 1, playerPosZ, true); List <byte> levelDATBytes = new List <byte>(); levelDat.WriteToBytes(levelDATBytes, false); var compressedLevelDAT = GZipStream.CompressBuffer(levelDATBytes.ToArray()); File.WriteAllBytes(Path.Combine(path, "level.dat"), compressedLevelDAT); Directory.CreateDirectory(Path.Combine(path, "region")); var options = new ParallelOptions() { MaxDegreeOfParallelism = 4 }; Parallel.ForEach(regions, options, (KeyValuePair <RegionLocation, Region> region) => { string name = $"r.{region.Key.x}.{region.Key.z}.mca"; using (var stream = new FileStream(Path.Combine(path, "region", name), FileMode.Create)) { RegionSerializer.WriteRegionToStream(region.Value, stream, gameVersion); } }); }
public NBTViewer(string path) { filename = Path.GetFileName(path); if (path.EndsWith(".mca")) { content = new NBTContent(); Region r = RegionLoader.LoadRegion(path); for (int z = 0; z < 32; z++) { for (int x = 0; x < 32; x++) { if (r.chunks[x, z] != null) { content.contents.Add($"Chunk [{x},{z}]", r.chunks[x, z].sourceNBT.contents); } } } } else { content = new NBTContent(RegionLoader.CreateZLibDecompressionStream(File.ReadAllBytes(path))); } //filename = "root"; //var root = new CompoundContainer(); //foreach(var k in content.contents.GetContentKeys("")) { // root.Add(k, content.contents.Get(k)); //} //content.contents.cont.Clear(); //content.contents.Add(filename, root); }
private static void WriteChunkToHeightmap(short[,] heightmap, NBTContent nbt, int localChunkX, int localChunkZ, HeightmapType mapType) { //int chunkDataX = (int)nbt.contents.Get("xPos") - regionPos.x * 32; //int chunkDataZ = (int)nbt.contents.Get("zPos") - regionPos.z * 32; //var chunkHM = nbt.GetHeightmapFromChunkNBT(mapType); try { ChunkData chunk = new ChunkData(null, nbt); chunk.WriteToHeightmap(heightmap, localChunkX, localChunkZ, mapType); /*for (int x = 0; x < 16; x++) * { * for (int z = 0; z < 16; z++) * { * byte y = (chunkHM != null) ? (byte)Math.Max(chunkHM[x, z] - 1, 0) : (byte)255; * if (y > 1) * { * while (y > 0 && !Blocks.IsBlockForMap(chunk.GetBlockAt(x, y, z).block, mapType)) * { * y--; * } * } * heightmap[localChunkX * 16 + x, localChunkZ * 16 + z] = y; * } * } */ } catch { } }
public ChunkData(Region region, NBTContent chunk) { containingRegion = region; sourceNBT = chunk; ChunkSerializer.ReadBlocksFromNBT(this, chunk.dataVersion); RecalculateSectionRange(); ReadEntitiesAndTileEntitiesFromNBT(chunk.contents); ReadBiomesFromNBT(chunk); }
public static NBTContent CreateCompoundForChunk(ChunkData chunk, Version version) { var nbt = new NBTContent(); nbt.dataVersion = version.GetDataVersion(); nbt.contents.Add("xPos", chunk.coords.x); nbt.contents.Add("zPos", chunk.coords.z); nbt.contents.Add("Status", "light"); ListContainer sections = new ListContainer(NBTTag.TAG_Compound); nbt.contents.Add("Sections", sections); nbt.contents.Add("TileEntities", new ListContainer(NBTTag.TAG_Compound)); nbt.contents.Add("Entities", new ListContainer(NBTTag.TAG_Compound)); //Add the rest of the tags and leave them empty nbt.contents.Add("Heightmaps", new CompoundContainer()); nbt.contents.Add("Structures", new CompoundContainer()); nbt.contents.Add("LiquidTicks", new ListContainer(NBTTag.TAG_Compound)); nbt.contents.Add("TileTicks", new ListContainer(NBTTag.TAG_Compound)); //Add post processing lists var ppList = new ListContainer(NBTTag.TAG_List); for (int i = 0; i < 16; i++) { ppList.Add(new ListContainer(NBTTag.TAG_Short)); } nbt.contents.Add("PostProcessing", ppList); //Write the actual data chunk.WriteToNBT(nbt.contents, version); /* * ListContainer postprocessing = new ListContainer(NBTTag.TAG_List); * for(int i = 0; i < 16; i++) postprocessing.Add("", new ListContainer(NBTTag.TAG_List)); * nbt.contents.Add("PostProcessing", postprocessing); * nbt.contents.Add("InhabitedTime", 0L); * nbt.contents.Add("LastUpdate", 0L); */ return(nbt); }
public World(Version version, int regionLowerX, int regionLowerZ, int regionUpperX, int regionUpperZ, string levelDatPath = null) { gameVersion = version; if (!string.IsNullOrEmpty(levelDatPath)) { using (var stream = File.OpenRead(levelDatPath)) { levelDat = new NBTContent(stream); } } regions = new Dictionary <RegionLocation, Region>(); for (int x = regionLowerX; x <= regionUpperX; x++) { for (int z = regionLowerZ; z <= regionUpperZ; z++) { var reg = new Region(x, z) { containingWorld = this }; regions.Add(new RegionLocation(x, z), reg); } } }
private NBTContent CreateLevelDAT(int playerPosX, int playerPosY, int playerPosZ, bool creativeModeWithCheats) { NBTContent levelDAT = new NBTContent(); var data = levelDAT.contents.AddCompound("Data"); data.Add <int>("DataVersion", 2504); data.Add <byte>("initialized", 0); data.Add <long>("LastPlayed", 0); data.Add <byte>("WasModded", 0); var datapacks = data.AddCompound("DataPacks"); datapacks.Add("Disabled", new ListContainer(NBTTag.TAG_String)); datapacks.Add("Enabled", new ListContainer(NBTTag.TAG_String)).Add(null, "vanilla"); data.AddCompound("GameRules"); data.Add("Player", CreatePlayerCompound(playerPosX, playerPosY, playerPosZ, creativeModeWithCheats)); var versionComp = data.AddCompound("Version"); versionComp.Add <int>("Id", 2504); versionComp.Add <string>("Name", "1.16"); versionComp.Add <byte>("Snapshot", 0); var worldGenComp = data.AddCompound("WorldGenSettings"); worldGenComp.AddCompound("dimensions"); worldGenComp.Add <byte>("bonus_chest", 0); worldGenComp.Add <byte>("generate_features", 1); worldGenComp.Add <long>("seed", new Random().Next(int.MaxValue)); data.AddList("ScheduledEvents", NBTTag.TAG_List); data.AddList("ServerBrands", NBTTag.TAG_String).Add("vanilla"); data.Add <byte>("allowCommands", (byte)(creativeModeWithCheats ? 1 : 0)); data.Add <double>("BorderCenterX", 0); data.Add <double>("BorderCenterZ", 0); data.Add <double>("BorderDamagePerBlock", 0.2d); data.Add <double>("BorderSafeZone", 5); data.Add <double>("BorderSize", 60000000); data.Add <double>("BorderSizeLerpTarget", 60000000); data.Add <long>("BorderSizeLerpTime", 0); data.Add <double>("BorderWarningBlocks", 5); data.Add <double>("BorderWarningTime", 15); data.Add <int>("clearWeatherTime", 0); data.Add <long>("DayTime", 0); data.Add <byte>("raining", 0); data.Add <int>("rainTime", new Random().Next(20000, 200000)); data.Add <byte>("thundering", 0); data.Add <int>("thunderTime", new Random().Next(50000, 100000)); data.Add <long>("Time", 0); data.Add <int>("version", 19133); data.Add <byte>("Difficulty", 2); data.Add <byte>("DifficultyLocked", 0); data.Add <int>("GameType", creativeModeWithCheats ? 1 : 0); data.Add <byte>("hardcore", 0); data.Add <string>("LevelName", worldName); data.Add <float>("SpawnAngle", 0); data.Add <int>("SpawnX", playerPosX); data.Add <int>("SpawnY", playerPosY); data.Add <int>("SpawnZ", playerPosZ); data.Add <int>("WanderingTraderSpawnChance", 50); data.Add <int>("WanderingTraderSpawnDelay", 24000); return(levelDAT); }
public NBTViewer(NBTContent data) { content = data; }