public void Write() { TAG_Compound data; using (FileStream level = new FileStream(LevelDatPath, FileMode.Open)) { using (GZipStream decompress = new GZipStream(level, CompressionMode.Decompress)) { MemoryStream mem = new MemoryStream(); decompress.CopyTo(mem); mem.Seek(0, SeekOrigin.Begin); data = new TAG_Compound(mem); } } ((TAG_Long)data["Data"]["RandomSeed"]).Payload = Seed; using (FileStream level = new FileStream(LevelDatPath, FileMode.Truncate)) { MemoryStream mem = new MemoryStream(); GZipStream compress = new GZipStream(mem, CompressionMode.Compress); data.Write(compress); compress.Close(); byte[] buffer = mem.ToArray(); level.Write(buffer, 0, buffer.Length); } }
public static void AddorRemoveBlocksSelection(RegionFile region, Bitmap b, Color selectionColor, int[] blockIds, bool add) { if (blockIds == null || blockIds.Length == 0) return; List<int> ids = new List<int>(blockIds); foreach (Chunk c in region.Chunks) { if (c.Root == null) continue; Coord chunkOffset = new Coord(region.Coords); chunkOffset.RegiontoChunk(); chunkOffset = new Coord(c.Coords.X - chunkOffset.X, c.Coords.Z - chunkOffset.Z); chunkOffset.ChunktoAbsolute(); TAG_Compound[] sections = new TAG_Compound[16]; int highest = -1; foreach (TAG t in (TAG[])c.Root["Level"]["Sections"]) { byte index = (byte)t["Y"]; if (index > highest) highest = index; sections[index] = (TAG_Compound)t; } //chunk exists but all blocks are air if (highest < 0) return; highest = ((highest + 1) * 16) - 1; for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { int y; if (c.ManualHeightmap[x + z * 16] >= 0) y = c.ManualHeightmap[x + z * 16]; else { y = GetHeight(sections, x, z, highest); c.ManualHeightmap[x + z * 16] = y; } if (y < 0) continue; if (ids.Contains(GetBlock(sections, x, y, z))) { b.SetPixel(OFFSETX + chunkOffset.X + x, OFFSETY + chunkOffset.Z + z, add ? selectionColor : Color.Transparent); } } } } }
public World(String path) { TAG_Compound data; LevelDatPath = path; using (FileStream level = new FileStream(path, FileMode.Open)) { using (GZipStream decompress = new GZipStream(level, CompressionMode.Decompress)) { MemoryStream mem = new MemoryStream(); decompress.CopyTo(mem); mem.Seek(0, SeekOrigin.Begin); data = new TAG_Compound(mem); } } Seed = (long)data["Data"]["RandomSeed"]; OriginalSeed = Seed; Version = (int)data["Data"]["version"]; WorldName = (String)data["Data"]["LevelName"]; WorldDir = Path.GetDirectoryName(path); }
private void RenderChunk(Chunk c, Bitmap b, int offsetX, int offsetY) { int[] heightmap = (int[])c.Root["Level"]["HeightMap"]; TAG_Compound[] sections = new TAG_Compound[16]; int highest = -1; foreach (TAG t in (TAG[])c.Root["Level"]["Sections"]) { byte index = (byte)t["Y"]; if (index > highest) highest = index; sections[index] = (TAG_Compound)t; } //chunk exists but all blocks are air if (highest < 0) return; highest = ((highest + 1) * 16) - 1; if (highest > UpperLimit) highest = UpperLimit; if (highest < LowerLimit) highest = LowerLimit; TAG biomes = null; c.Root["Level"].TryGetValue("Biomes", out biomes); for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { int y = GetHeight(sections, x, z, highest, LowerLimit, Only, Exclude); if (y < LowerLimit) continue; byte id, data; GetBlock(sections, x, y, z, out id, out data); byte biome = 255; if(ConsiderBiomes && biomes != null) biome = ((byte[])biomes)[x + z * 16]; Color color = ColorPalette.Lookup(id, data, biome); if (Transparency) { y--; while (color.A < 255 && y >= LowerLimit) { GetBlock(sections, x, y, z, out id, out data); if (Only != null && !Only.Contains(id)) id = 0; if (Exclude != null && Exclude.Contains(id)) id = 0; Color c2 = ColorPalette.Lookup(id, data, biome); color = Blend(color, c2); y--; } } else color = Color.FromArgb(255, color.R, color.G, color.B); if (ShowHeight) { //brighten/darken by height; arbitrary value, but /seems/ to look okay color = AddtoColor(color, (int)(y / 1.7 - 42)); } b.SetPixel(offsetX + x, offsetY + z, color); } } }
private static byte GetLight(TAG_Compound[] sections, int x, int y, int z) { byte light = 15; int section = (int)Math.Floor(y / 16.0); if (sections[section] != null) { int offset = ((y % 16) * 16 + z) * 16 + x; light = ((byte[])sections[section]["BlockLight"])[offset >> 1]; if (offset % 2 == 0) light = (byte)(light & 0x0F); else light = (byte)((light >> 4) & 0x0F); } if (light > 15) light = 15; else if (light < 4) light = 4; return light; }
private static int GetHeight(TAG_Compound[] sections, int x, int z, int yStart = 255, int yEnd = 0, HashSet<byte> only = null, HashSet<byte> exclude = null) { int h = yStart; for (; h >= yEnd; h--) { byte b = GetBlock(sections, x, h, z); if (b != 0) { if(only != null && only.Contains(b)) return h; else if(exclude != null && !exclude.Contains(b)) return h; else if(only == null && exclude == null) return h; } } return yEnd - 1; }
private static void GetBlock(TAG_Compound[] sections, int x, int y, int z, out byte id, out byte data) { id = 0; data = 0; int section = (int)Math.Floor(y / 16.0); if (sections[section] != null) { int offset = ((y % 16) * 16 + z) * 16 + x; id = ((byte[])sections[section]["Blocks"])[offset]; data = ((byte[])sections[section]["Data"])[offset >> 1]; if (offset % 2 == 0) data = (byte)(data & 0x0F); else data = (byte)((data >> 4) & 0x0F); } }
private static byte GetBlock(TAG_Compound[] sections, int x, int y, int z) { byte id, data; GetBlock(sections, x, y, z, out id, out data); return id; }
private void openToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog dialog = new OpenFileDialog(); dialog.InitialDirectory = lastPath; dialog.Filter = "Minecraft (*.dat, mcr, mca)|*.dat;*.mcr;*.mca"; if (dialog.ShowDialog() != DialogResult.OK) return; lastPath = Path.GetDirectoryName(dialog.FileName); lastFile = Path.GetFileName(dialog.FileName); txtOutput.Text = ""; if (Path.GetExtension(dialog.FileName) == ".dat") { MemoryStream data = new MemoryStream(); using (GZipStream decompress = new GZipStream(dialog.OpenFile(), CompressionMode.Decompress)) { decompress.CopyTo(data); decompress.Close(); } data.Seek(0, SeekOrigin.Begin); TAG_Compound rootContainer = new TAG_Compound(data); txtOutput.Text += rootContainer.ToString(); } else { txtOutput.Text = new RegionFile(dialog.FileName).ToString(); } int indent = 0; StringBuilder sb = new StringBuilder(); foreach (String line in txtOutput.Lines) { if (line.Length > 0 && line[0] == '{') { sb.Append(new String('\t', indent)).AppendLine(line); indent++; } else if (line.Length > 0 && line[0] == '}') { indent--; sb.Append(new String('\t', indent)).AppendLine(line); } else sb.Append(new String('\t', indent)).AppendLine(line); } txtOutput.Text = sb.ToString(); }
private static void RenderChunkTerrain(Object state) { Object[] parameters = (Object[])state; Chunk c = (Chunk)parameters[0]; Bitmap b = (Bitmap)parameters[1]; int offsetX = (int)parameters[2]; int offsetY = (int)parameters[3]; TAG_Compound[] sections = new TAG_Compound[16]; int highest = -1; foreach (TAG t in (TAG[])c.Root["Level"]["Sections"]) { byte index = (byte)t["Y"]; if (index > highest) highest = index; sections[index] = (TAG_Compound)t; } if (c.ManualHeightmap == null) { c.ManualHeightmap = new int[256]; for (int i = 0; i < c.ManualHeightmap.Length; i++) c.ManualHeightmap[i] = -1; } //chunk exists but all blocks are air if (highest < 0) { if (Interlocked.Decrement(ref taskCount) == 0) signal.Set(); return; } Color[,] pixels = new Color[16, 16]; highest = ((highest + 1) * 16) - 1; TAG biomes = null; c.Root["Level"].TryGetValue("Biomes", out biomes); for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { int y; if (c.ManualHeightmap[x + z * 16] >= 0) y = c.ManualHeightmap[x + z * 16]; else { y = GetHeight(sections, x, z, highest); c.ManualHeightmap[x + z * 16] = y; } if (y < 0) continue; byte id, data; GetBlock(sections, x, y, z, out id, out data); byte biome = (byte)Biome.Unspecified; if(biomes != null && Settings.BiomeFoliage) biome = ((byte[])biomes)[x + z * 16]; Color color = ColorPalette.Lookup(id, data, biome); if (Settings.Transparency) { y--; while (color.A < 255 && y >= 0) { GetBlock(sections, x, y, z, out id, out data); Color c2 = ColorPalette.Lookup(id, data, biome); color = Blend(color, c2); y--; } } else color = Color.FromArgb(255, color.R, color.G, color.B); //brighten/darken by height; arbitrary value, but /seems/ to look okay color = AddtoColor(color, (int)(y / 1.7 - 42)); pixels[x, z] = color; } } mutex.WaitOne(); for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { b.SetPixel(offsetX + x, offsetY + z, pixels[x, z]); } } mutex.ReleaseMutex(); if (Interlocked.Decrement(ref taskCount) == 0) signal.Set(); }
private static int GetHeight(TAG_Compound[] sections, int x, int z, int yStart = 255) { int h = yStart; for (; h >= 0; h--) { byte b = GetBlock(sections, x, h, z); if (b != 0) return h; } return -1; }