Files

289 lines
11 KiB
C#
Raw Permalink Normal View History

2025-12-19 15:58:45 -07:00
using Mono.Options;
2023-01-04 21:08:49 -08:00
using System.Text;
2025-04-13 15:18:03 -06:00
using Repackinator.Core.Actions;
2023-01-04 21:08:49 -08:00
using System.Diagnostics;
2025-04-13 15:18:03 -06:00
using Repackinator.Core.Models;
using Repackinator.Core.Logging;
2023-01-04 21:08:49 -08:00
2025-12-19 15:58:45 -07:00
namespace Repackinator.Shell.Console
2023-01-04 21:08:49 -08:00
{
public static class ConsoleRepack
{
2023-01-11 20:44:58 +01:00
public const string Action = "Repack";
2023-01-04 21:08:49 -08:00
public static string Input { get; set; } = string.Empty;
public static string Output { get; set; } = string.Empty;
2025-11-20 10:02:17 -08:00
public static string Unpack { get; set; } = string.Empty;
2023-01-04 21:08:49 -08:00
public static string Grouping { get; set; } = "NONE";
2025-11-22 17:30:18 -08:00
public static bool Uppercase { get; set; } = false;
2023-01-04 21:08:49 -08:00
public static bool Recurse { get; set; } = false;
2024-10-08 17:21:55 -06:00
public static bool NoSplit { get; set; } = false;
2023-01-04 21:08:49 -08:00
public static string Log { get; set; } = string.Empty;
2025-11-22 17:30:18 -08:00
public static bool Compress { get; set; } = false;
public static bool Scrub { get; set; } = false;
public static bool TrimScrub { get; set; } = false;
2023-01-04 21:08:49 -08:00
public static bool ShowHelp { get; set; } = false;
public static bool Wait { get; set; } = false;
public static OptionSet GetOptions()
{
return new OptionSet {
{ "i|input=", "Input folder", i => Input = i },
{ "o|output=", "Output folder", o => Output = o },
2025-12-19 16:23:18 -07:00
{ "p|unpack=", "Unpack folder for temporary extraction (optional)", p => Unpack = p},
2023-01-04 21:08:49 -08:00
{ "g|grouping=", "Grouping (None *default*, Region, Letter, RegionLetter, LetterRegion)", g => Grouping = g.ToUpper() },
2025-11-22 17:30:18 -08:00
{ "u|uppercase", "Uppercase", u => Uppercase = u != null },
{ "r|recurse", "Recurse (Traverse Subdirs)", r => Recurse = r != null },
{ "c|compress", "Compress (CCI)", c => Compress = c != null },
{ "s|scrub", "Scrub", s => Scrub = s != null },
{ "t|trimscrub", "TrimScrub", t => TrimScrub = t != null },
2024-10-08 17:21:55 -06:00
{ "n|nosplit", "No Split of output file", n => NoSplit = n != null },
2023-01-04 21:08:49 -08:00
{ "l|log=", "log file", l => Log = l },
{ "h|help", "show help", h => ShowHelp = h != null },
{ "w|wait", "Wait on exit", w => Wait = w != null }
};
}
public static void ShowOptionDescription()
{
2023-01-11 20:44:58 +01:00
System.Console.WriteLine();
System.Console.WriteLine("Repack Action...");
System.Console.WriteLine();
System.Console.WriteLine("This action is used to repackinate your collection of xbox disk images.");
System.Console.WriteLine();
GetOptions().WriteOptionDescriptions(System.Console.Out);
2023-01-04 21:08:49 -08:00
}
public static void Process(string version, string[] args)
{
try
{
var options = GetOptions();
options.Parse(args);
if (ShowHelp)
{
2023-01-11 20:44:58 +01:00
ConsoleUtil.ShowHelpHeaderForAction(version, Action, options);
2023-01-04 21:08:49 -08:00
ConsoleUtil.ProcessWait(Wait);
return;
}
if (string.IsNullOrEmpty(Input))
{
throw new OptionException("input not specified.", "input");
}
2025-11-20 10:02:17 -08:00
string input;
try
{
input = Path.GetFullPath(Input);
}
catch (ArgumentException)
2023-01-04 21:08:49 -08:00
{
throw new OptionException("input is not a valid directory.", "input");
}
2025-11-20 10:02:17 -08:00
if (!Directory.Exists(input))
{
throw new OptionException("input directory does not exist.", "input");
}
2023-01-04 21:08:49 -08:00
if (string.IsNullOrEmpty(Output))
{
throw new OptionException("output not specified.", "output");
}
2025-11-20 10:02:17 -08:00
string output;
try
{
output = Path.GetFullPath(Output);
}
catch (ArgumentException)
{
throw new OptionException("output is not a valid directory.", "output");
}
2025-04-13 15:18:03 -06:00
var groupingValue = GroupingOptionType.None;
2023-01-04 21:08:49 -08:00
if (string.Equals(Grouping, "NONE"))
{
2025-04-13 15:18:03 -06:00
groupingValue = GroupingOptionType.None;
2023-01-04 21:08:49 -08:00
}
else if (string.Equals(Grouping, "REGION"))
{
2025-04-13 15:18:03 -06:00
groupingValue = GroupingOptionType.Region;
2023-01-04 21:08:49 -08:00
}
else if (string.Equals(Grouping, "LETTER"))
{
2025-04-13 15:18:03 -06:00
groupingValue = GroupingOptionType.Letter;
2023-01-04 21:08:49 -08:00
}
else if (string.Equals(Grouping, "REGIONLETTER"))
{
2025-04-13 15:18:03 -06:00
groupingValue = GroupingOptionType.RegionLetter;
2023-01-04 21:08:49 -08:00
}
else if (string.Equals(Grouping, "LETTERREGION"))
{
2025-04-13 15:18:03 -06:00
groupingValue = GroupingOptionType.LetterRegion;
2023-01-04 21:08:49 -08:00
}
else
{
throw new OptionException("grouping is not valid.", "grouping");
}
2025-04-13 15:18:03 -06:00
var compressValue = CompressOptionType.None;
2025-11-22 17:30:18 -08:00
if (Compress)
2023-09-01 12:01:59 -07:00
{
2025-04-13 15:18:03 -06:00
compressValue = CompressOptionType.CCI;
2023-09-01 12:01:59 -07:00
}
2025-11-21 23:59:37 -08:00
var scrubValue = ScrubOptionType.None;
2025-11-22 17:30:18 -08:00
if (TrimScrub)
2025-11-21 23:59:37 -08:00
{
scrubValue = ScrubOptionType.TrimScrub;
}
2025-11-22 17:30:18 -08:00
else if (Scrub)
{
scrubValue = ScrubOptionType.Scrub;
}
2025-11-21 23:59:37 -08:00
2025-11-20 10:02:17 -08:00
string unpack;
if (!string.IsNullOrEmpty(Unpack))
{
try
{
unpack = Path.GetFullPath(Unpack);
if (!Directory.Exists(unpack))
{
Directory.CreateDirectory(unpack);
}
}
catch (ArgumentException)
{
throw new OptionException("unpack is not a valid directory.", "unpack");
}
}
2023-01-04 21:08:49 -08:00
if (!Directory.Exists(output))
{
Directory.CreateDirectory(output);
}
2025-11-20 14:15:25 -08:00
string log;
2023-01-04 21:08:49 -08:00
FileStream? logStream = null;
2025-11-20 14:15:25 -08:00
if (!string.IsNullOrEmpty(Log))
2023-01-04 21:08:49 -08:00
{
2025-11-20 14:15:25 -08:00
try
{
log = Path.GetFullPath(Log);
2025-11-20 16:43:54 -08:00
string? dir = Path.GetDirectoryName(log);
if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
2025-11-20 14:15:25 -08:00
{
2025-11-20 16:43:54 -08:00
Directory.CreateDirectory(dir);
2025-11-20 14:15:25 -08:00
}
logStream = File.OpenWrite(log);
}
2025-11-20 16:43:54 -08:00
catch (ArgumentException)
2025-11-20 14:15:25 -08:00
{
throw new OptionException("log is not a valid filepath.", "log");
}
2023-01-04 21:08:49 -08:00
}
var logger = new Action<LogMessage>((logMessage) =>
{
var formattedTime = logMessage.Time.ToString("HH:mm:ss");
var message = $"{formattedTime} {logMessage.Level} - {logMessage.Message}";
System.Console.WriteLine(message);
2025-11-20 14:15:25 -08:00
logStream?.Write(Encoding.UTF8.GetBytes(message));
2023-01-04 21:08:49 -08:00
});
var config = new Config
{
InputPath = Input,
OutputPath = Output,
2025-11-20 10:02:17 -08:00
UnpackPath = Unpack,
2025-04-13 15:18:03 -06:00
GroupingOption = groupingValue,
2023-01-04 21:08:49 -08:00
RecurseInput = Recurse,
2025-11-22 17:30:18 -08:00
Uppercase = Uppercase,
2025-04-13 15:18:03 -06:00
CompressOption = compressValue,
2024-10-08 17:21:55 -06:00
NoSplit = NoSplit,
2025-11-21 23:59:37 -08:00
ScrubOption = scrubValue,
2023-01-04 21:08:49 -08:00
};
var gameData = GameDataHelper.LoadGameData();
var prevMessage = string.Empty;
2025-12-19 17:54:45 -07:00
var previousProgress1 = -1.0f;
var previousProgress2 = -1.0f;
var progress = new Action<Repackinator.Core.Models.ProgressInfo>((progressInfo) =>
{
if (!string.IsNullOrEmpty(progressInfo.Progress1Text) && progressInfo.Progress1Text != prevMessage)
{
if (!string.IsNullOrEmpty(prevMessage))
{
System.Console.WriteLine();
}
System.Console.WriteLine(progressInfo.Progress1Text);
prevMessage = progressInfo.Progress1Text;
}
var amount1 = (float)Math.Round(progressInfo.Progress1 * 100);
if (amount1 != previousProgress1)
{
if (amount1 < 10)
{
System.Console.Write($"Progress {amount1}%");
}
else if (amount1 < 100)
{
System.Console.Write($"Progress {amount1}%");
}
else
{
System.Console.Write($"Progress {amount1}%");
}
System.Console.CursorLeft = 0;
previousProgress1 = amount1;
}
if (progressInfo.Progress1 >= 1.0f && !string.IsNullOrEmpty(progressInfo.Progress2Text))
{
var amount2 = (float)Math.Round(progressInfo.Progress2 * 100);
if (amount2 != previousProgress2)
{
System.Console.WriteLine();
System.Console.Write($"{progressInfo.Progress2Text} - ");
if (amount2 < 10)
{
System.Console.Write($"Progress {amount2}%");
}
else if (amount2 < 100)
{
System.Console.Write($"Progress {amount2}%");
}
else
{
System.Console.Write($"Progress {amount2}%");
}
System.Console.CursorLeft = 0;
previousProgress2 = amount2;
}
}
});
2023-01-04 21:08:49 -08:00
var repacker = new Repacker();
2025-12-19 17:54:45 -07:00
repacker.StartRepacking(gameData, config, progress, logger, new Stopwatch(), default);
2023-01-04 21:08:49 -08:00
2025-11-20 10:02:17 -08:00
logStream?.Dispose();
2023-01-04 21:08:49 -08:00
System.Console.WriteLine();
2025-12-19 17:54:45 -07:00
System.Console.WriteLine("Repack completed.");
2023-01-04 21:08:49 -08:00
}
catch (OptionException e)
{
2025-12-19 16:19:12 -07:00
ConsoleUtil.ShowOptionException(e, Action, version);
2023-01-04 21:08:49 -08:00
}
2025-12-20 19:58:42 -07:00
ConsoleUtil.ProcessWait(Wait);
2023-01-04 21:08:49 -08:00
}
}
}
2025-12-19 15:58:45 -07:00