Ejemplo n.º 1
0
        public static Task <IBlockDataSourceRegion> GetRegion_Pre(BlockDataSourceDimension source, RegionPoint point, CancellationToken token)
        {
            if (!source.HasRegion(point))
            {
                return(Task.FromResult <IBlockDataSourceRegion>(null));
            }
            if (!source.RegionsPath.StartsWith(Utils.Remote))
            {
                return(null);
            }

            return(GetOnlineRegion(source, point, token).ContinueWith <IBlockDataSourceRegion>(t =>
                                                                                               new BlockDataSourceRegion(new RegionStream(point, t.Result), source.BlockRegistry, source.BiomeRegistry, source.BiomeNumberMap)));
        }
Ejemplo n.º 2
0
        private static async Task <Stream> GetOnlineRegion(BlockDataSourceDimension source, RegionPoint point, CancellationToken token)
        {
            int i = 0;

            byte[] data = null;
            string key  = $"{source.RegionsPath.Substring(Utils.Remote.Length + 1)}/r.{point.X}.{point.Z}.mca";

            while (data == null)
            {
                try
                {
                    data = await Utils.GetOrAddCached(key, TimeSpan.TicksPerMinute * 3 / 2, () => Utils.GetDataAsync(key, token));
                }
                catch
                {
                    Utils.RemoveCached(key);
                    if (++i > 5 || token.IsCancellationRequested)
                    {
                        throw;
                    }
                }
            }
            return(new MemoryStream(data));
        }
Ejemplo n.º 3
0
        public void DoProcess()
        {
            var now = DateTime.Now;

            Logger.Information("World path: {source}", _origin);
            var regionRect = RegionRect.Empty;

            var directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            var dtoAutoFactory   = new DtoAutoFactory();
            var blockTagRegistry = new BlockTagRegistry(new MetapackReader(dtoAutoFactory)
                                                        .ReadFromFolder(Path.Combine(directoryName, "Metapacks", _metapack)).GetAllTags());
            var blockRegistry        = new BlockRegistry();
            var blockTagAssociations = new BlockTagAssociations();
            var settingsProvider     =
                new SliceGeneratorBlockSettingsProvider(blockTagAssociations);
            var blockFinder        = new BlockFinder();
            var associationManager = new BlockTagAssociationManager(blockRegistry,
                                                                    blockTagRegistry, blockTagAssociations,
                                                                    blockFinder);
            var stylesheet = dtoAutoFactory.Create <IStylesheet>();

            DefaultStylesheet.CreateDefaultStyleSheet(dtoAutoFactory, stylesheet);

            var blockResolver = new BlockResolver(blockFinder, blockTagRegistry,
                                                  blockTagAssociations);
            var blockStyleProvider = new TerrainRendererBlockStyleProvider(new TerrainRendererBlockStylesGenerator(
                                                                               new[]
            {
                stylesheet
            }, blockResolver));

            var regionBufferSource = new RegionBufferSource(Path.Combine(_origin, "region"));
            var blockDataSource    = new BlockDataSourceDimension(regionBufferSource,
                                                                  blockRegistry);
            var sliceTileGeneratorOptions = new SliceGeneratorOptions
            {
                UseUndergroundXRay = _isUnderground,
                MaxY = (short)(_isUnderground ? 122 : byte.MaxValue)
            };
            var blockRect = regionBufferSource.BoundsRegionRect.ToBlockRect();
            var regions   = regionBufferSource.Regions;

            Logger.Information("World size: {count} regions", regions.Count);
            Logger.Information("World size: {w} x {h} blocks", blockRect.Width, blockRect.Height);
            Logger.Information("World rectangle: r{area}", regionBufferSource.BoundsRegionRect);
            if (!regionRect.IsEmpty)
            {
                blockRect = blockRect.Intersect(regionRect.ToBlockRect());
            }
            Logger.Information("Rendering rectangle: r{area}", blockRect.ToRegionRect());
            Logger.Information("Output path: {output}", _dest);

            var renderer = new TerrainRenderer(new TerrainRendererOptions
            {
                NightMode = false,
                TransparentUnderground = _isUnderground,
                UnknownBlockStyle      = new TerrainRendererBlockStyle
                {
                    BaseColor = new Rgba32(0, 192, 0)
                }
            }, blockStyleProvider,
                                               settingsProvider);
            var tileSize       = 256;
            var intRect        = blockRect.ToIntRect(tileSize);
            var renderedChunks = 0;
            var num1           = 0;
            var tilesTotal     = regions.Count * (512 / tileSize) * (512 / tileSize);
            var tilesProcessed = 0;
            var tilesSkipped   = 0;
            var tilesRendered  = 0;
            var tileStore      = GetTileStore(tileSize, 0);

            GenerateHtml(blockRect.ToRegionRect(), directoryName, _name, regions);
            Logger.Information("Rendering zoom level {zoom}", 0);
            foreach (var regionPoint1 in intRect.ToBlockRect(tileSize).ToRegionRect().EnumRegionsZx())
            {
                var regionPoint = regionPoint1;
                if (regions.ContainsKey(regionPoint))
                {
                    var num2 = renderedChunks;
                    Parallel.ForEach(
                        intRect.Intersect(regionPoint.ToBlockRect().ToIntRect(tileSize)).EnumPointsZx(),
                        RenderTile);
                    var num3 = renderedChunks;
                    if (num2 != num3)
                    {
                        ++num1;
                    }

                    void RenderTile(IntPoint tilePoint)
                    {
                        Interlocked.Increment(ref tilesProcessed);
                        var regionTimestamp = blockDataSource.GetRegionTimestamp(regionPoint);

                        if (!_force)
                        {
                            var tileMetadata = tileStore.GetTileMetadata(tilePoint);
                            if (tileMetadata != null &&
                                GetHash(
                                    regionTimestamp.ToString(CultureInfo.InvariantCulture)) ==
                                tileMetadata.SourceVersionHash && tileStore.HasTile(tilePoint))
                            {
                                ++tilesSkipped;
                                return;
                            }
                        }

                        Logger.Information(
                            "Rendering tile z{zoom} t{tile} [{progress}]", 0, tilePoint,
                            $"{(object) Math.Round(tilesProcessed / (double) tilesTotal * 100.0):F0}%");
                        var rgba32Array = new Rgba32[tileSize * tileSize];

                        for (var index = 0; index < rgba32Array.Length; ++index)
                        {
                            rgba32Array[index] = Rgba32.Black;
                        }
                        Interlocked.Add(ref renderedChunks,
                                        renderer.Render(blockDataSource,
                                                        blockRegistry,
                                                        blockRect.Intersect(tilePoint.ToBlockRect(tileSize)),
                                                        rgba32Array, tileSize, 0, 0, 0, sliceTileGeneratorOptions, CancellationToken.None)
                                        .GetAwaiter().GetResult().RenderedChunks);
                        Interlocked.Increment(ref tilesRendered);
                        using (var image =
                                   Image.LoadPixelData(rgba32Array, tileSize, tileSize))
                            tileStore.UpdateOrAddTileAsync(tilePoint, new ImageTile(tilePoint, tileSize, image))
                            .GetAwaiter().GetResult();
                        tileStore.SetTileMetadata(tilePoint, new TileMetadata
                        {
                            SourceVersionHash =
                                GetHash(
                                    regionTimestamp.ToString(CultureInfo.InvariantCulture)),
                            VersionHash =
                                GetHash(
                                    DateTime.Now.ToString(CultureInfo.InvariantCulture))
                        });
                    }
                }
            }

            var timeSpan1        = DateTime.Now - now;
            var tileRenderResult = RenderZoomOutTiles(intRect, tileSize,
                                                      regions.Keys.ToArray());
            var timeSpan2 = DateTime.Now - now;

            Logger.Information("Finished");
            Logger.Information("{count} Terrain tiles", tilesTotal);
            Logger.Information("{count} Terrain tiles unchanged", tilesSkipped);
            Logger.Information("{count} Terrain tiles rendered", tilesRendered);
            Logger.Information(
                "Elapsed time: {time}, {chunkSpeed} chunks/s, {regionSpeed} regions/s",
                timeSpan1.ToString("d\\.hh\\:mm\\:ss"),
                ((int)(renderedChunks / timeSpan1.TotalSeconds)).ToString(),
                $"{(object) ((double) num1 / timeSpan1.TotalSeconds):F2}");
            Logger.Information("{count} Zoom-out tiles", tileRenderResult.TilesTotal);
            Logger.Information("{count} Zoom-out tiles unchanged", tileRenderResult.TilesSkipped);
            Logger.Information("{count} Zoom-out tiles rendered", tileRenderResult.TilesRendered);
            Logger.Information("Elapsed time total: {time}",
                               timeSpan2.ToString("d\\.hh\\:mm\\:ss"));
        }