static ReturnCode ParseOptions([NotNull] string[] args) { if (args == null) { throw new ArgumentNullException("args"); } string jpegQualityString = null, imageFormatName = null, importerName = null, angleString = null, isoCatModeName = null, regionString = null; string importerList = MapUtility.GetImporters().JoinToString(c => c.Format.ToString()); bool printHelp = false; opts = new OptionSet() .Add("a=|angle=", "Angle (orientation) from which the map is drawn. May be -90, 0, 90, 180, or 270. Default is 0.", o => angleString = o) .Add("f=|filter=", "Pattern to filter input filenames, e.g. \"*.dat\" or \"builder*\". " + "Applicable only when a directory name is given as input.", o => inputFilter = o) .Add("i=|importer=", "Optional: Converter used for importing/loading maps. " + "Available importers: Auto (default), " + importerList, o => importerName = o) .Add("e=|export=", "Image format to use for exporting. " + "Supported formats: PNG (default), BMP, GIF, JPEG, TIFF.", o => imageFormatName = o) .Add("m=|mode=", "Rendering mode. May be \"normal\" (default), \"cut\" (cuts out a quarter of the map, revealing inside), " + "\"peeled\" (strips the outer-most layer of blocks), \"chunk\" (renders only a specified region of the map).", o => isoCatModeName = o) .Add("g|nogradient", "Disables altitude-based gradient/shading on terrain.", o => noGradient = (o != null)) .Add("s|noshadows", "Disables rendering of shadows.", o => noShadows = (o != null)) .Add("o=|output=", "Path to save images to. " + "If not specified, images will be saved to the maps' directories.", o => outputDirName = o) .Add("y|overwrite", "Do not ask for confirmation to overwrite existing files.", o => overwrite = (o != null)) .Add("q=|quality=", "Sets JPEG compression quality. Between 0 and 100. Default is 80. " + "Applicable only when exporting images to .jpg or .jpeg.", o => jpegQualityString = o) .Add("r|recursive", "Look through all subdirectories for map files. " + "Applicable only when a directory name is given as input.", o => recursive = (o != null)) .Add("region=", "Region of the map to render. Should be given in following format: \"region=x1,y1,z1,x2,y2,z2\" " + "Applicable only when rendering mode is set to \"chunk\".", o => regionString = o) .Add("w|seethroughwater", "Makes all water see-through, instead of mostly opaque.", o => seeThroughWater = (o != null)) .Add("l|seethroughlava", "Makes all lava partially see-through, instead of opaque.", o => seeThroughLava = (o != null)) .Add("u|uncropped", "Does not crop the finished map image, leaving some empty space around the edges.", o => uncropped = (o != null)) .Add("?|h|help", "Prints out the options.", o => printHelp = (o != null)); List <string> pathList; try { pathList = opts.Parse(args); } catch (OptionException ex) { Console.Error.Write("MapRenderer: "); Console.Error.WriteLine(ex.Message); PrintHelp(); return(ReturnCode.ArgumentError); } if (printHelp) { PrintHelp(); Environment.Exit((int)ReturnCode.Success); } if (pathList.Count != 1) { Console.Error.WriteLine("MapRenderer: At least one file or directory name required."); PrintUsage(); return(ReturnCode.ArgumentError); } inputPath = pathList[0]; // Parse angle if (angleString != null && (!Int32.TryParse(angleString, out angle) || angle != -90 && angle != 0 && angle != 180 && angle != 270)) { Console.Error.WriteLine("MapRenderer: Angle must be a number: -90, 0, 90, 180, or 270"); return(ReturnCode.ArgumentError); } // Parse mode if (isoCatModeName != null && !EnumUtil.TryParse(isoCatModeName, out mode, true)) { Console.Error.WriteLine( "MapRenderer: Rendering mode should be: \"normal\", \"cut\", \"peeled\", or \"chunk\"."); return(ReturnCode.ArgumentError); } // Parse region (if in chunk mode) if (mode == IsoCatMode.Chunk) { if (regionString == null) { Console.Error.WriteLine("MapRenderer: Region parameter is required when mode is set to \"chunk\""); return(ReturnCode.ArgumentError); } try { string[] regionParts = regionString.Split(','); region = new BoundingBox(Int32.Parse(regionParts[0]), Int32.Parse(regionParts[1]), Int32.Parse(regionParts[2]), Int32.Parse(regionParts[3]), Int32.Parse(regionParts[4]), Int32.Parse(regionParts[5])); } catch { Console.Error.WriteLine( "MapRenderer: Region should be specified in the following format: \"--region=x1,y1,z1,x2,y2,z2\""); } } else if (regionString != null) { Console.Error.WriteLine( "MapRenderer: Region parameter is given, but rendering mode was not set to \"chunk\""); } // Parse given image format if (imageFormatName != null) { if (imageFormatName.Equals("BMP", StringComparison.OrdinalIgnoreCase)) { exportFormat = ImageFormat.Bmp; imageFileExtension = ".bmp"; } else if (imageFormatName.Equals("GIF", StringComparison.OrdinalIgnoreCase)) { exportFormat = ImageFormat.Gif; imageFileExtension = ".gif"; } else if (imageFormatName.Equals("JPEG", StringComparison.OrdinalIgnoreCase) || imageFormatName.Equals("JPG", StringComparison.OrdinalIgnoreCase)) { exportFormat = ImageFormat.Jpeg; imageFileExtension = ".jpg"; } else if (imageFormatName.Equals("PNG", StringComparison.OrdinalIgnoreCase)) { exportFormat = ImageFormat.Png; imageFileExtension = ".png"; } else if (imageFormatName.Equals("TIFF", StringComparison.OrdinalIgnoreCase) || imageFormatName.Equals("TIF", StringComparison.OrdinalIgnoreCase)) { exportFormat = ImageFormat.Tiff; imageFileExtension = ".tif"; } else { Console.Error.WriteLine( "MapRenderer: Image file format should be: BMP, GIF, JPEG, PNG, or TIFF"); return(ReturnCode.ArgumentError); } } // Parse JPEG quality if (jpegQualityString != null) { if (exportFormat == ImageFormat.Jpeg) { if (!Int32.TryParse(jpegQualityString, out jpegQuality) || jpegQuality < 0 || jpegQuality > 100) { Console.Error.WriteLine( "MapRenderer: JpegQuality parameter should be a number between 0 and 100"); return(ReturnCode.ArgumentError); } } else { Console.Error.WriteLine( "MapRenderer: JpegQuality parameter given, but image export format was not set to \"JPEG\"."); } } // parse importer name if (importerName != null && !importerName.Equals("auto", StringComparison.OrdinalIgnoreCase)) { MapFormat importFormat; if (!EnumUtil.TryParse(importerName, out importFormat, true) || (mapImporter = MapUtility.GetImporter(importFormat)) == null) { Console.Error.WriteLine("Unsupported importer \"{0}\"", importerName); PrintUsage(); return(ReturnCode.UnrecognizedImporter); } } return(ReturnCode.Success); }
static int Main(string[] args) { Logger.Logged += OnLogged; Logger.DisableFileLogging(); ReturnCode optionParsingResult = ParseOptions(args); if (optionParsingResult != ReturnCode.Success) { return((int)optionParsingResult); } // parse importer name if (importerName != null && !importerName.Equals("auto", StringComparison.OrdinalIgnoreCase)) { MapFormat importFormat; if (!EnumUtil.TryParse(importerName, out importFormat, true)) { Console.Error.WriteLine("Unsupported importer \"{0}\"", importerName); PrintUsage(); return((int)ReturnCode.UnrecognizedImporter); } p.MapImporter = MapUtility.GetImporter(importFormat); if (p.MapImporter == null) { Console.Error.WriteLine("Loading from \"{0}\" is not supported", importFormat); PrintUsage(); return((int)ReturnCode.UnsupportedLoadFormat); } } // check input paths bool hadFile = false, hadDir = false; foreach (string inputPath in p.InputPathList) { if (hadDir) { Console.Error.WriteLine("MapRenderer: Only one directory may be specified at a time."); return((int)ReturnCode.ArgumentError); } // check if input path exists, and if it's a file or directory try { if (File.Exists(inputPath)) { hadFile = true; } else if (Directory.Exists(inputPath)) { hadDir = true; if (hadFile) { Console.Error.WriteLine("MapRenderer: Cannot mix directories and files in input."); return((int)ReturnCode.ArgumentError); } p.DirectoryMode = true; if (!p.OutputDirGiven) { p.OutputDirName = inputPath; } } else { Console.Error.WriteLine("MapRenderer: Cannot locate \"{0}\"", inputPath); return((int)ReturnCode.InputPathNotFound); } } catch (Exception ex) { Console.Error.WriteLine("MapRenderer: {0}: {1}", ex.GetType().Name, ex.Message); return((int)ReturnCode.PathError); } } // initialize image encoder ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders(); p.ImageEncoder = codecs.FirstOrDefault(codec => codec.FormatID == p.ExportFormat.Guid); if (p.ImageEncoder == null) { Console.Error.WriteLine("MapRenderer: Specified image encoder is not supported."); return((int)ReturnCode.UnsupportedSaveFormat); } // check recursive flag if (p.Recursive && !p.DirectoryMode) { Console.Error.WriteLine("MapRenderer: Recursive flag is given, but input is not a directory."); return((int)ReturnCode.ArgumentError); } // check input filter if (p.InputFilter != null && !p.DirectoryMode) { Console.Error.WriteLine("MapRenderer: Filter param is given, but input is not a directory."); return((int)ReturnCode.ArgumentError); } // check regex filter if (p.UseRegex) { try { p.FilterRegex = new Regex(p.InputFilter); } catch (ArgumentException ex) { Console.Error.WriteLine("MapRenderer: Cannot parse filter regex: {0}", ex.Message); return((int)ReturnCode.ArgumentError); } } // check if output dir exists; create it if needed if (p.OutputDirName != null) { try { if (!Directory.Exists(p.OutputDirName)) { Directory.CreateDirectory(p.OutputDirName); } } catch (Exception ex) { Console.Error.WriteLine("MapRenderer: Error checking output directory: {0}: {1}", ex.GetType().Name, ex.Message); } } Console.Write("Counting files... "); // process inputs, one path at a time foreach (string inputPath in p.InputPathList) { ProcessInputPath(inputPath); } int totalFiles = InputPaths.Count; Console.WriteLine(totalFiles); if (totalFiles > 0) { int actualThreadCount = Math.Min(p.ThreadCount, InputPaths.Count); RenderWorker[] workers = new RenderWorker[actualThreadCount]; for (int i = 0; i < workers.Length; i++) { workers[i] = new RenderWorker(WorkQueue, ResultQueue, p); workers[i].Start(); } int inputsProcessed = 0; int resultsProcessed = 0; while (resultsProcessed < totalFiles) { if (inputsProcessed < totalFiles) { // load and enqueue another map for rendering if (WorkQueue.Count < actualThreadCount) { RenderTask newTask = InputPaths.Dequeue(); if (LoadMap(newTask)) { WorkQueue.Enqueue(newTask); } else { resultsProcessed++; } inputsProcessed++; } else { Thread.Sleep(1); } // try dequeue a rendered image for saving RenderTask resultTask; if (ResultQueue.TryDequeue(out resultTask)) { int percent = (resultsProcessed * 100 + 100) / totalFiles; SaveImage(percent, resultTask); resultsProcessed++; } } else { // no more maps to load -- just wait for results int percent = (resultsProcessed * 100 + 100) / totalFiles; SaveImage(percent, ResultQueue.WaitDequeue()); resultsProcessed++; } } } Console.WriteLine("MapRenderer: Processed {0} files in {1:0.00} seconds", totalFiles, DateTime.UtcNow.Subtract(StartTime).TotalSeconds); return((int)ReturnCode.Success); }
static int Main(string[] args) { Logger.Logged += OnLogged; ReturnCode optionParsingResult = ParseOptions(args); if (optionParsingResult != ReturnCode.Success) { return((int)optionParsingResult); } // parse importer name if (importerName != null && !importerName.Equals("auto", StringComparison.OrdinalIgnoreCase)) { MapFormat importFormat; if (!EnumUtil.TryParse(importerName, out importFormat, true) || (importer = MapUtility.GetImporter(importFormat)) == null) { Console.Error.WriteLine("Unsupported importer \"{0}\"", importerName); PrintUsage(); return((int)ReturnCode.UnrecognizedImporter); } } // parse exporter format MapFormat exportFormat; if (!EnumUtil.TryParse(exporterName, out exportFormat, true) || (exporter = MapUtility.GetExporter(exportFormat)) == null) { Console.Error.WriteLine("Unsupported exporter \"{0}\"", exporterName); PrintUsage(); return((int)ReturnCode.UnrecognizedExporter); } // check if input path exists, and if it's a file or directory bool directoryMode; try { if (File.Exists(inputPath)) { directoryMode = false; if (outputDirName == null) { outputDirName = Paths.GetDirectoryNameOrRoot(inputPath); } } else if (Directory.Exists(inputPath)) { directoryMode = true; if (outputDirName == null) { outputDirName = Paths.GetDirectoryNameOrRoot(inputPath); } } else { Console.Error.WriteLine("MapConverter: Cannot locate \"{0}\"", inputPath); return((int)ReturnCode.InputDirNotFound); } if (!Directory.Exists(outputDirName)) { Directory.CreateDirectory(outputDirName); } } catch (Exception ex) { Console.Error.WriteLine("MapConverter: {0}: {1}", ex.GetType().Name, ex.Message); return((int)ReturnCode.PathError); } // check recursive flag if (recursive && !directoryMode) { Console.Error.WriteLine("MapConverter: Recursive flag is given, but input is not a directory."); } // check input filter if (inputFilter != null && !directoryMode) { Console.Error.WriteLine("MapConverter: Filter param is given, but input is not a directory."); } if (!recursive && importer != null && importer.StorageType == MapStorageType.Directory) { // single-directory conversion ConvertOneMap(new DirectoryInfo(inputPath)); } else if (!directoryMode) { // single-file conversion ConvertOneMap(new FileInfo(inputPath)); } else { // possible single-directory conversion if (!recursive && ConvertOneMap(new DirectoryInfo(inputPath))) { return((int)ReturnCode.Success); } // otherwise, go through all files inside the given directory SearchOption recursiveOption = (recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); DirectoryInfo inputDirInfo = new DirectoryInfo(inputPath); if (inputFilter == null) { inputFilter = "*"; } foreach (var dir in inputDirInfo.GetDirectories(inputFilter, recursiveOption)) { ConvertOneMap(dir); } foreach (var file in inputDirInfo.GetFiles(inputFilter, recursiveOption)) { ConvertOneMap(file); } } return((int)ReturnCode.Success); }
static int Main(string[] args) { Logger.Logged += OnLogged; Logger.DisableFileLogging(); ReturnCode optionParsingResult = ParseOptions(args); if (optionParsingResult != ReturnCode.Success) { return((int)optionParsingResult); } // parse importer name if (importerName != null && !importerName.Equals("auto", StringComparison.OrdinalIgnoreCase)) { MapFormat importFormat; if (!EnumUtil.TryParse(importerName, out importFormat, true)) { Console.Error.WriteLine("MapConverter: Unsupported importer \"{0}\"", importerName); PrintUsage(); return((int)ReturnCode.UnrecognizedImporter); } importer = MapUtility.GetImporter(importFormat); if (importer == null) { Console.Error.WriteLine("MapConverter: Loading from \"{0}\" is not supported", importFormat); PrintUsage(); return((int)ReturnCode.UnsupportedLoadFormat); } } // parse exporter format MapFormat exportFormat; if (!EnumUtil.TryParse(exporterName, out exportFormat, true)) { Console.Error.WriteLine("MapConverter: Unrecognized exporter \"{0}\"", exporterName); PrintUsage(); return((int)ReturnCode.UnrecognizedExporter); } exporter = MapUtility.GetExporter(exportFormat); if (exporter == null) { Console.Error.WriteLine("MapConverter: Saving to \"{0}\" is not supported", exportFormat); PrintUsage(); return((int)ReturnCode.UnsupportedSaveFormat); } // check input paths bool hadFile = false, hadDir = false; foreach (string inputPath in inputPathList) { if (hadDir) { Console.Error.WriteLine("MapConverter: Only one directory may be specified at a time."); return((int)ReturnCode.ArgumentError); } // check if input path exists, and if it's a file or directory try { if (File.Exists(inputPath)) { hadFile = true; } else if (Directory.Exists(inputPath)) { hadDir = true; if (hadFile) { Console.Error.WriteLine("MapConverter: Cannot mix directories and files in input."); return((int)ReturnCode.ArgumentError); } directoryMode = true; if (!outputDirGiven) { outputDirName = inputPath; } } else { Console.Error.WriteLine("MapConverter: Cannot locate \"{0}\"", inputPath); return((int)ReturnCode.InputPathNotFound); } } catch (Exception ex) { Console.Error.WriteLine("MapConverter: {0}: {1}", ex.GetType().Name, ex.Message); return((int)ReturnCode.PathError); } } // check recursive flag if (recursive && !directoryMode) { Console.Error.WriteLine("MapConverter: Recursive flag is given, but input is not a directory."); return((int)ReturnCode.ArgumentError); } // check input filter if (inputFilter != null && !directoryMode) { Console.Error.WriteLine("MapConverter: Filter param is given, but input is not a directory."); return((int)ReturnCode.ArgumentError); } // check regex filter if (useRegex) { try { filterRegex = new Regex(inputFilter); } catch (ArgumentException ex) { Console.Error.WriteLine("MapConverter: Cannot parse filter regex: {0}", ex.Message); return((int)ReturnCode.ArgumentError); } } // check if output dir exists; create it if needed if (outputDirName != null) { try { if (!Directory.Exists(outputDirName)) { Directory.CreateDirectory(outputDirName); } } catch (Exception ex) { Console.Error.WriteLine("MapRenderer: Error checking output directory: {0}: {1}", ex.GetType().Name, ex.Message); } } // process inputs, one path at a time foreach (string inputPath in inputPathList) { ReturnCode code = ProcessInputPath(inputPath); if (code != ReturnCode.Success) { return((int)code); } } return((int)ReturnCode.Success); }
static int Main(string[] args) { Logger.Logged += OnLogged; Logger.DisableFileLogging(); ReturnCode optionParsingResult = ParseOptions(args); if (optionParsingResult != ReturnCode.Success) { return((int)optionParsingResult); } // parse importer name if (importerName != null && !importerName.Equals("auto", StringComparison.OrdinalIgnoreCase)) { MapFormat importFormat; if (!EnumUtil.TryParse(importerName, out importFormat, true)) { Console.Error.WriteLine("Unsupported importer \"{0}\"", importerName); PrintUsage(); return((int)ReturnCode.UnrecognizedImporter); } mapImporter = MapUtility.GetImporter(importFormat); if (mapImporter == null) { Console.Error.WriteLine("Loading from \"{0}\" is not supported", importFormat); PrintUsage(); return((int)ReturnCode.UnsupportedLoadFormat); } } // check input paths bool hadFile = false, hadDir = false; foreach (string inputPath in inputPathList) { if (hadDir) { Console.Error.WriteLine("MapRenderer: Only one directory may be specified at a time."); return((int)ReturnCode.ArgumentError); } // check if input path exists, and if it's a file or directory try { if (File.Exists(inputPath)) { hadFile = true; } else if (Directory.Exists(inputPath)) { hadDir = true; if (hadFile) { Console.Error.WriteLine("MapRenderer: Cannot mix directories and files in input."); return((int)ReturnCode.ArgumentError); } directoryMode = true; if (!outputDirGiven) { outputDirName = inputPath; } } else { Console.Error.WriteLine("MapRenderer: Cannot locate \"{0}\"", inputPath); return((int)ReturnCode.InputPathNotFound); } } catch (Exception ex) { Console.Error.WriteLine("MapRenderer: {0}: {1}", ex.GetType().Name, ex.Message); return((int)ReturnCode.PathError); } } // initialize image encoder ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders(); imageEncoder = codecs.FirstOrDefault(codec => codec.FormatID == exportFormat.Guid); if (imageEncoder == null) { Console.Error.WriteLine("MapRenderer: Specified image encoder is not supported."); return((int)ReturnCode.UnsupportedSaveFormat); } // create and configure the renderer renderer = new IsoCat { SeeThroughLava = seeThroughLava, SeeThroughWater = seeThroughWater, Mode = mode, Gradient = !noGradient, DrawShadows = !noShadows }; if (mode == IsoCatMode.Chunk) { renderer.ChunkCoords[0] = region.XMin; renderer.ChunkCoords[1] = region.YMin; renderer.ChunkCoords[2] = region.ZMin; renderer.ChunkCoords[3] = region.XMax; renderer.ChunkCoords[4] = region.YMax; renderer.ChunkCoords[5] = region.ZMax; } switch (angle) { case 90: renderer.Rotation = 1; break; case 180: renderer.Rotation = 2; break; case 270: case -90: renderer.Rotation = 3; break; } // check recursive flag if (recursive && !directoryMode) { Console.Error.WriteLine("MapRenderer: Recursive flag is given, but input is not a directory."); return((int)ReturnCode.ArgumentError); } // check input filter if (inputFilter != null && !directoryMode) { Console.Error.WriteLine("MapRenderer: Filter param is given, but input is not a directory."); return((int)ReturnCode.ArgumentError); } // check regex filter if (useRegex) { try { filterRegex = new Regex(inputFilter); } catch (ArgumentException ex) { Console.Error.WriteLine("MapRenderer: Cannot parse filter regex: {0}", ex.Message); return((int)ReturnCode.ArgumentError); } } // check if output dir exists; create it if needed if (outputDirName != null) { try { if (!Directory.Exists(outputDirName)) { Directory.CreateDirectory(outputDirName); } } catch (Exception ex) { Console.Error.WriteLine("MapRenderer: Error checking output directory: {0}: {1}", ex.GetType().Name, ex.Message); } } // process inputs, one path at a time foreach (string inputPath in inputPathList) { ReturnCode code = ProcessInputPath(inputPath); if (code != ReturnCode.Success) { return((int)code); } } return((int)ReturnCode.Success); }