コード例 #1
0
        public Task GenerateForAllWorlds()
        {
            return(Task.Run(() =>
            {
                using (var scope = _serviceFactory.CreateScope())
                {
                    var context = scope.ServiceProvider.GetService <DatabaseContext>();

                    var worlds = context.Servers.Include(s => s.World)
                                 .Where(s => s.World != null)
                                 .Select(s => s.World)
                                 .ToList();

                    foreach (var world in worlds)
                    {
                        try
                        {
                            _logger.LogInformation($"Generating map for world. ID: {world.ID} Path: '{world.Path}'");

                            var worldPath = _environment.BuildPath(_pathOptions.WorldDirectory, world.Path);
                            var mapPath = _environment.BuildPath(_pathOptions.WorldDirectory, "map", world.Path);
                            var parser = _worldParserFactory.Create(worldPath);

                            if (!parser.GetRegions(TARGET_REGION).Any())
                            {
                                _logger.LogInformation($"World has no region files. Skipping. ID: {world.ID} Path: '{world.Path}'");
                                continue;
                            }

                            var fileBasedRegionCache = new FileBasedRegionCache(worldPath);
                            var renderer = _mapRendererFactory.Create2DRender(parser, fileBasedRegionCache);

                            var renderResult = renderer.GenerateBlockBitmap(TARGET_REGION);

                            renderResult.Bitmap.Save(Path.Combine(mapPath, "map.png"));

                            renderResult.Bitmap.Mutate(x => x.Resize(new Size(200, 200)));
                            renderResult.Bitmap.Save(Path.Combine(mapPath, "map_thumb.png"));

                            var mapRenderResultDataFilePath = Path.Combine(mapPath, "render-result.json");
                            File.WriteAllText(mapRenderResultDataFilePath, JsonConvert.SerializeObject(new
                            {
                                OffsetX = renderResult.OffsetX,
                                OffsetZ = renderResult.OffsetZ,
                                UnknownBlocks = renderResult.UnknownRenderEntites.OrderByDescending(x => x.Value)
                            }));

                            _logger.LogInformation($"Finished generating map for world. ID: {world.ID} Path: '{world.Path}'");
                        }
                        catch (Exception e)
                        {
                            _logger.LogError(new EventId(), e, $"An error ocurred when generating map for world. ID: {world.ID} Path: '{world.Path}' ");
                        }
                    }
                }
            }));
        }
コード例 #2
0
ファイル: ImageRepository.cs プロジェクト: nojan1/Mineman
        public async Task <Image> Add(ImageAddModel imageAddModel)
        {
            string zipName             = $"{Guid.NewGuid().ToString("N")}.zip";
            string imageContentZipPath = _environment.BuildPath(_pathOptions.ImageZipFileDirectory, zipName);

            using (var file = File.Create(imageContentZipPath))
            {
                var stream = imageAddModel.ImageContents.First().OpenReadStream();
                stream.Seek(0, SeekOrigin.Begin);
                await stream.CopyToAsync(file);
            }

            var image = new Image
            {
                Name = imageAddModel.DisplayName,
                ImageContentZipPath = zipName,
                Type         = imageAddModel.Type,
                SupportsMods = !string.IsNullOrEmpty(imageAddModel.ModDir),
                ModDirectory = imageAddModel.ModDir ?? "",
                BuildStatus  = null
            };

            await _context.Images.AddAsync(image);

            await _context.SaveChangesAsync();

            return(image);
        }
コード例 #3
0
ファイル: WorldInfoService.cs プロジェクト: nojan1/Mineman
        public Task GenerateForAllWorlds()
        {
            return(Task.Run(() =>
            {
                using (var scope = _serviceFactory.CreateScope())
                {
                    var context = scope.ServiceProvider.GetService <DatabaseContext>();

                    var worlds = context.Servers.Include(s => s.World)
                                 .Where(s => s.World != null)
                                 .Select(s => s.World)
                                 .ToList();

                    foreach (var world in worlds)
                    {
                        try
                        {
                            _logger.LogInformation($"Parsing info for world. ID: {world.ID} Path: '{world.Path}'");

                            var worldPath = _environment.BuildPath(_pathOptions.WorldDirectory, world.Path);
                            var parser = _worldParserFactory.Create(worldPath);

                            var worldInfo = new WorldInfoModel();
                            PopulatePlayers(parser, worldInfo);
                            PopulateBlockEntities(parser, worldInfo);

                            worldInfo.SpawnX = parser.Level?.SpawnX ?? 0;
                            worldInfo.SpawnY = parser.Level?.SpawnY ?? 0;
                            worldInfo.SpawnZ = parser.Level?.SpawnZ ?? 0;

                            var worldInfoFilePath = _environment.BuildPath(_pathOptions.WorldDirectory, "info", world.Path, "worldinfo.json");
                            File.WriteAllText(worldInfoFilePath, JsonConvert.SerializeObject(worldInfo));

                            _logger.LogInformation($"Finished parsing info for world. ID: {world.ID} Path: '{world.Path}'");
                        }
                        catch (Exception e)
                        {
                            _logger.LogError(new EventId(), e, $"An error ocurred when parsing info for world. ID: {world.ID} Path: '{world.Path}' ");
                        }
                    }
                }
            }));
        }
コード例 #4
0
ファイル: WorldRepository.cs プロジェクト: nojan1/Mineman
        public async Task <MapImagePaths> GetMapImagePaths(int worldId)
        {
            var world = await _context.Worlds.FindAsync(worldId);

            var fullSizePath = _environment.BuildPath(_pathOptions.WorldDirectory, "map", world.Path, "map.png");
            var thumbPath    = _environment.BuildPath(_pathOptions.WorldDirectory, "map", world.Path, "map_thumb.png");

            return(new MapImagePaths
            {
                MapPath = File.Exists(fullSizePath) ? fullSizePath : null,
                MapThumbPath = File.Exists(thumbPath) ? thumbPath : null
            });
        }
コード例 #5
0
ファイル: ModController.cs プロジェクト: nojan1/Mineman
        public async Task <IActionResult> Download(int modId)
        {
            var mod = await _modRepository.Get(modId);

            if (mod == null)
            {
                return(BadRequest());
            }

            var modPath = _environment.BuildPath(_pathOptions.ModDirectory, mod.Path);

            using (var stream = System.IO.File.OpenRead(modPath))
            {
                return(File(stream, "application/octect-stream", mod.Path));
            }
        }
コード例 #6
0
        public async Task <Mod> Add(ModAddModel modAddModel)
        {
            string fileName    = modAddModel.ModFile.First().FileName;
            string modFilePath = _environment.BuildPath(_pathOptions.ModDirectory, fileName);

            using (var file = File.Create(modFilePath))
            {
                var stream = modAddModel.ModFile.First().OpenReadStream();
                stream.Seek(0, SeekOrigin.Begin);
                await stream.CopyToAsync(file);
            }

            var mod = new Mod
            {
                DisplayName = modAddModel.DisplayName,
                Path        = fileName
            };

            await _context.Mods.AddAsync(mod);

            await _context.SaveChangesAsync();

            return(mod);
        }
コード例 #7
0
ファイル: ImageManager.cs プロジェクト: nojan1/Mineman
        public async Task CreateImage(Image image)
        {
            _logger.LogInformation($"About to create docker image for mineman image. ImageID: {image.ID}");

            string imageId        = null;
            var    logBuilder     = new StringBuilder();
            bool   buildSucceeded = true;

            var dockerArchivePath = Path.GetTempFileName();
            var dockerFilePath    = _environment.BuildPath(_dockerOptions.DockerfilePath);
            var workingDir        = _environment.BuildPath(_pathOptions.ImageZipFileDirectory, Guid.NewGuid().ToString("N"));

            using (ClaimResource(image.ID))
            {
                try
                {
                    string zipPath;

                    if (string.IsNullOrEmpty(image.ImageContentZipPath))
                    {
                        if (string.IsNullOrEmpty(image.RemoteHash))
                        {
                            throw new ArgumentException("No ImageContentZipPath and no RemoteHash, unable to create image");
                        }

                        var name = $"{Guid.NewGuid().ToString("N")}.zip";
                        zipPath = _environment.BuildPath(_pathOptions.ImageZipFileDirectory, name);

                        using (var fstream = File.OpenWrite(zipPath))
                        {
                            var stream = await _remoteImageRepository.GetDownloadStream(image.RemoteHash);

                            await stream.CopyToAsync(fstream);
                        }

                        image.ImageContentZipPath = name;
                    }
                    else
                    {
                        zipPath = _environment.BuildPath(_pathOptions.ImageZipFileDirectory, image.ImageContentZipPath);
                    }

                    using (var zipArchive = new ZipArchive(File.OpenRead(zipPath)))
                    {
                        zipArchive.ExtractToDirectory(workingDir);
                    }

                    File.Copy(dockerFilePath, Path.Combine(workingDir, "Dockerfile"), true);

                    _logger.LogInformation($"Image creation folder preparation complete. ImageID: {image.ID}");

                    using (var stream = File.OpenWrite(dockerArchivePath))
                    {
                        using (var writer = WriterFactory.Open(stream, ArchiveType.Tar, new WriterOptions(CompressionType.None)))
                        {
                            writer.WriteAll(workingDir, "*", SearchOption.AllDirectories);
                        }
                    }

                    var responseStream = await _dockerClient.Images.BuildImageFromDockerfileAsync(File.OpenRead(dockerArchivePath),
                                                                                                  new Docker.DotNet.Models.ImageBuildParameters
                    {
                        Dockerfile = "Dockerfile",
                        //TODO: Fix so that tags can be used on built images...
                        //Tags = new List<string>
                        //{
                        //    image.Name.Replace(' ', '_')
                        //},
                        Labels = new Dictionary <string, string>()
                        {
                            { "creator", "mineman" }
                        }
                    },
                                                                                                  CancellationToken.None);

                    _logger.LogInformation($"Parsing build log and waiting for docker image id. ImageID: {image.ID}");

                    logBuilder = new StringBuilder();
                    imageId    = await WaitForId(responseStream, logBuilder);

                    _logger.LogInformation($"Image created in docker. ImageID: {image.ID}, DockerID: {imageId}");
                }
                catch (Exception e)
                {
                    _logger.LogError(new EventId(), e, $"Error building image! ImageID: '{image.ID}'");
                    buildSucceeded = false;
                }
                finally
                {
                    //Cleanup
                    try { File.Delete(dockerArchivePath); } catch { /* Don't care about errors here, just hope it got deleted */ }
                    try { Directory.Delete(workingDir, true); } catch { /* Don't care about errors here, just hope it got deleted */ }
                }

                image.BuildStatus = new ImageBuildStatus
                {
                    BuildSucceeded = buildSucceeded,
                    Log            = logBuilder.ToString()
                };
                image.DockerId = imageId;

                _context.Update(image);
                await _context.SaveChangesAsync();
            }
        }
コード例 #8
0
ファイル: ServerManager.cs プロジェクト: nojan1/Mineman
        private async Task CreateContainer(Server server)
        {
            _logger.LogInformation($"About to create container for server. ServerID: {server.ID}, ImageID: {server.Image.ID}");

            var worldPath            = _environment.BuildPath(_pathOptions.WorldDirectory, server.World.Path);
            var serverPropertiesPath = _environment.BuildPath(_pathOptions.ServerPropertiesDirectory, $"{server.ID}-server.properties");

            var heapMax   = server.MemoryAllocationMB;
            var heapStart = Convert.ToInt32(server.MemoryAllocationMB * 0.6);

            var javaOpts = $"JAVA_OPTS=-Xmx{heapMax}m -Xms{heapStart}m";

            WriteServerProperties(server);

            var binds = new List <string>
            {
                $"{worldPath}:/server/world",
                $"{serverPropertiesPath}:/server/server.properties"
            };

            if (server.Image.SupportsMods && server.Mods != null)
            {
                foreach (var mod in server.Mods)
                {
                    var containerPath = $"/server/{server.Image.ModDirectory}/{mod.Path}";
                    var localPath     = _environment.BuildPath(_pathOptions.ModDirectory, mod.Path);

                    binds.Append($"{localPath}:{containerPath}");
                }
            }

            var response = await _dockerClient.Containers.CreateContainerAsync(new CreateContainerParameters
            {
                Image = server.Image.DockerId,
                Env   = new List <string> {
                    javaOpts
                },
                ExposedPorts = new Dictionary <string, EmptyStruct>()
                {
                    { "25565/tcp", new EmptyStruct() },
                    { "26565/udp", new EmptyStruct() },
                    { "27565/tcp", new EmptyStruct() }
                },
                Labels = new Dictionary <string, string>()
                {
                    { "creator", "mineman" }
                },
                HostConfig = new HostConfig
                {
                    Binds        = binds,
                    PortBindings = new Dictionary <string, IList <PortBinding> >
                    {
                        { "25565/tcp", new List <PortBinding> {
                              new PortBinding {
                                  HostIP = "0.0.0.0", HostPort = server.MainPort.ToString()
                              }
                          } },
                        { "26565/udp", new List <PortBinding> {
                              new PortBinding {
                                  HostIP = "0.0.0.0", HostPort = server.QueryPort.ToString()
                              }
                          } },
                        { "27565/tcp", new List <PortBinding> {
                              new PortBinding {
                                  HostIP = "0.0.0.0", HostPort = server.RconPort.ToString()
                              }
                          } }
                    },
                    RestartPolicy = new RestartPolicy {
                        Name = RestartPolicyKind.UnlessStopped
                    }
                }
            });

            server.ContainerID   = response.ID;
            server.NeedsRecreate = false;

            _context.Update(server);
            await _context.SaveChangesAsync();

            await _infoClient.ImageBuildComplete(server.ID);
        }