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}' "); } } } })); }
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); }
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}' "); } } } })); }
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 }); }
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)); } }
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); }
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(); } }
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); }