private static void RunOptionsAndReturnExitCode(CliOptions opts)
        {
            Console.Clear();
            var cgui = new ConsoleGui();

            var pbBlocks = new ConsoleGuiProgressBar(0, 0, Console.WindowWidth, 0, 1)
            {
                ForegroundColor = ConsoleColor.Green,
                BackgroundColor = ConsoleColor.DarkGray
            };

            var lBlocksTotal     = new ConsoleGuiLabel(0, 1, "Total Blocks    : {0}");
            var lBlocksRemaining = new ConsoleGuiLabel(0, 2, "Remaining Blocks: {0}");
            var lBlocksFailed    = new ConsoleGuiLabel(0, 3, "Failed Blocks   : {0}");
            var lStatus          = new ConsoleGuiLabel(0, 4, "Status          : {0}");

            cgui.Add(pbBlocks);
            cgui.Add(lBlocksTotal);
            cgui.Add(lBlocksRemaining);
            cgui.Add(lBlocksFailed);
            cgui.Add(lStatus);

            var failed = new List <int>();

            var inputMap  = NbtMap.Load(opts.InputMap);
            var outputMap = NbtMap.Load(opts.OutputMap);

            var inputSchematic = new NBTFile(opts.InputSchematic);
            var tag            = new NbtTree(inputSchematic.GetDataInputStream()).Root;

            var bLower    = tag["Blocks"].ToTagByteArray().Data;
            var addBlocks = new byte[(bLower.Length >> 1) + 1];

            if (tag.ContainsKey("AddBlocks"))
            {
                addBlocks = tag["AddBlocks"].ToTagByteArray().Data;
            }

            lStatus.Value = "Processing...";

            for (var index = 0; index < bLower.Length; index++)
            {
                short oldId;
                if ((index & 1) == 1)
                {
                    oldId = (short)(((addBlocks[index >> 1] & 0x0F) << 8) + (bLower[index] & 0xFF));
                }
                else
                {
                    oldId = (short)(((addBlocks[index >> 1] & 0xF0) << 4) + (bLower[index] & 0xFF));
                }

                if (!TranslateId(oldId, inputMap, outputMap, out var newId))
                {
                    failed.Add(oldId);
                }

                bLower[index]         = (byte)(newId & 0xFF);
                addBlocks[index >> 1] = (byte)(((index & 1) == 1) ?
                                               addBlocks[index >> 1] & 0xF0 | (newId >> 8) & 0xF
                    : addBlocks[index >> 1] & 0xF | ((newId >> 8) & 0xF) << 4);

                // Gui
                lBlocksTotal.Value     = index + 1;
                lBlocksRemaining.Value = bLower.Length - index - 1;
                lBlocksFailed.Value    = failed.Count;
                pbBlocks.Value         = (float)index / bLower.Length;

                if (index % 10000 == 0)
                {
                    cgui.Render();
                }
            }

            cgui.Render();

            tag["Blocks"] = new TagNodeByteArray(bLower);

            if (!tag.ContainsKey("AddBlocks"))
            {
                tag.Add("AddBlocks", new TagNodeByteArray(addBlocks));
            }
            else
            {
                tag["AddBlocks"] = new TagNodeByteArray(addBlocks);
            }

            lStatus.Value = "Saving...";
            cgui.Render();

            var schematicFile = new NBTFile(opts.OutputSchematic);

            using (var nbtStream = schematicFile.GetDataOutputStream())
            {
                if (nbtStream == null)
                {
                    return;
                }

                var tree = new NbtTree(tag, "Schematic");
                tree.WriteTo(nbtStream);
            }

            lStatus.Value = "Done. Press Enter.";
            cgui.Render();

            Console.WriteLine();
            foreach (var i in failed)
            {
                Console.WriteLine($"Failed ID: {i}");
            }

            Console.ReadKey();
        }
Ejemplo n.º 2
0
        private static void GenerateScrf(GenerateOptions opts)
        {
            var world      = AnvilWorld.Open(opts.WorldPath);
            var donorWorld = AnvilWorld.Open(opts.OriginalPath);

            var dim          = opts.WorldDim;
            var manager      = world.GetChunkManager(dim).ToList();
            var donorManager = donorWorld.GetChunkManager(dim);

            var inputMap  = NbtMap.Load(Path.Combine(opts.OriginalPath, "cdfidmap.nbt"));
            var outputMap = NbtMap.Load(Path.Combine(opts.WorldPath, "cdfidmap.nbt"));

            var chunkBounds = new ChunkBounds(opts.ChunkBounds);

            if (!chunkBounds.BoundsExist)
            {
                Console.WriteLine("Input bounds not in the correct format");
                return;
            }

            var diff = new ScarifStructure(outputMap);

            Console.Clear();
            var cgui = new ConsoleGui();

            var pbChunks = new ConsoleGuiProgressBar(0, 0, Console.WindowWidth, 0, 1)
            {
                ForegroundColor = ConsoleColor.Green,
                BackgroundColor = ConsoleColor.DarkGray
            };

            var lChunksTotal     = new ConsoleGuiLabel(0, 1, "Total Chunks    : {0}");
            var lChunksRemaining = new ConsoleGuiLabel(0, 2, "Remaining Chunks: {0}");
            var lStatus          = new ConsoleGuiLabel(0, 3, "Status          : {0}");

            var lChunksProcessed = new ConsoleGuiLabel(Console.WindowWidth / 2, 1, "Processed Chunks : {0}");
            var lChunksSkipped   = new ConsoleGuiLabel(Console.WindowWidth / 2, 2, "Skipped Chunks   : {0}");
            var lChunksDiffed    = new ConsoleGuiLabel(Console.WindowWidth / 2, 3, "Diffed Chunks    : {0}");
            var lBlocksDiffed    = new ConsoleGuiLabel(Console.WindowWidth / 2, 4, "Diffed Blocks    : {0}");
            var lTilesDiffed     = new ConsoleGuiLabel(Console.WindowWidth / 2, 5, "Diffed TEs       : {0}");

            cgui.Add(pbChunks);

            cgui.Add(lChunksTotal);
            cgui.Add(lChunksRemaining);
            cgui.Add(lStatus);

            cgui.Add(lChunksProcessed);
            cgui.Add(lChunksSkipped);
            cgui.Add(lChunksDiffed);
            cgui.Add(lBlocksDiffed);
            cgui.Add(lTilesDiffed);

            var processedChunks = 0;
            var diffedChunks    = 0;
            var diffedBlocks    = 0;
            var diffedTiles     = 0;
            var skipped         = 0;

            lStatus.Value = "Processing...";

            for (var i = 1; i <= manager.Count; i++)
            {
                var chunk = manager[i - 1];

                if (i > 1)
                {
                    manager[i - 2] = null;
                }

                pbChunks.Value = (float)i / manager.Count;

                if (!donorManager.ChunkExists(chunk.X, chunk.Z) || !chunkBounds.CoarseContains(chunk))
                {
                    skipped++;
                    continue;
                }

                processedChunks++;

                var pos        = new ChunkPosition(chunk.X, chunk.Z);
                var otherChunk = donorManager.GetChunk(chunk.X, chunk.Z);

                var numBlocksBefore = diffedBlocks;
                for (var y = 0; y < 256; y++)
                {
                    for (var x = 0; x < 16; x++)
                    {
                        for (var z = 0; z < 16; z++)
                        {
                            if (!chunkBounds.Contains(chunk.X * 16 + x, y, chunk.Z * 16 + z))
                            {
                                continue;
                            }

                            var     blockId   = (short)chunk.Blocks.GetID(x, y, z);
                            var     blockData = chunk.Blocks.GetData(x, y, z);
                            NbtTree nbt       = null;
                            var     te        = chunk.Blocks.GetTileEntity(x, y, z);
                            if (te != null)
                            {
                                nbt = new NbtTree(te.Source, "tile");
                            }

                            var     blockIdOriginal   = (short)otherChunk.Blocks.GetID(x, y, z);
                            var     blockDataOriginal = otherChunk.Blocks.GetData(x, y, z);
                            NbtTree nbtOriginal       = null;
                            var     teOriginal        = otherChunk.Blocks.GetTileEntity(x, y, z);
                            if (teOriginal != null)
                            {
                                nbtOriginal = new NbtTree(teOriginal.Source, "tile");
                            }

                            if (!inputMap.ContainsKey(blockIdOriginal) || !outputMap.ContainsKey(blockId))
                            {
                                continue;
                            }

                            if (inputMap[blockIdOriginal] == outputMap[blockId] && blockDataOriginal == blockData && nbtOriginal == nbt)
                            {
                                continue;
                            }

                            if (nbtOriginal != nbt)
                            {
                                diffedTiles++;
                            }

                            diffedBlocks++;
                            diff.Add(pos, new BlockPosition(x, y, z), new ScarifBlock(blockId, blockData, nbt));
                        }
                    }
                }

                if (diffedBlocks != numBlocksBefore)
                {
                    diffedChunks++;
                }

                lChunksTotal.Value     = i.ToString("N0");
                lChunksRemaining.Value = (manager.Count - i).ToString("N0");

                lChunksProcessed.Value = processedChunks.ToString("N0");
                lBlocksDiffed.Value    = diffedBlocks.ToString("N0");
                lTilesDiffed.Value     = diffedTiles.ToString("N0");
                lChunksDiffed.Value    = diffedChunks.ToString("N0");
                lChunksSkipped.Value   = skipped.ToString("N0");

                cgui.Render();
            }

            lStatus.Value = "Saving...";
            cgui.Render();

            diff.Save(opts.DiffOutput);

            lStatus.Value = "Done. Press Enter.";
            cgui.Render();

            Console.ReadKey();
        }