Files
2025-12-20 19:58:42 -07:00

289 lines
11 KiB
C#

using Mono.Options;
using System.Text;
using Repackinator.Core.Actions;
using System.Diagnostics;
using Repackinator.Core.Models;
using Repackinator.Core.Logging;
namespace Repackinator.Shell.Console
{
public static class ConsoleRepack
{
public const string Action = "Repack";
public static string Input { get; set; } = string.Empty;
public static string Output { get; set; } = string.Empty;
public static string Unpack { get; set; } = string.Empty;
public static string Grouping { get; set; } = "NONE";
public static bool Uppercase { get; set; } = false;
public static bool Recurse { get; set; } = false;
public static bool NoSplit { get; set; } = false;
public static string Log { get; set; } = string.Empty;
public static bool Compress { get; set; } = false;
public static bool Scrub { get; set; } = false;
public static bool TrimScrub { get; set; } = false;
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 },
{ "p|unpack=", "Unpack folder for temporary extraction (optional)", p => Unpack = p},
{ "g|grouping=", "Grouping (None *default*, Region, Letter, RegionLetter, LetterRegion)", g => Grouping = g.ToUpper() },
{ "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 },
{ "n|nosplit", "No Split of output file", n => NoSplit = n != null },
{ "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()
{
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);
}
public static void Process(string version, string[] args)
{
try
{
var options = GetOptions();
options.Parse(args);
if (ShowHelp)
{
ConsoleUtil.ShowHelpHeaderForAction(version, Action, options);
ConsoleUtil.ProcessWait(Wait);
return;
}
if (string.IsNullOrEmpty(Input))
{
throw new OptionException("input not specified.", "input");
}
string input;
try
{
input = Path.GetFullPath(Input);
}
catch (ArgumentException)
{
throw new OptionException("input is not a valid directory.", "input");
}
if (!Directory.Exists(input))
{
throw new OptionException("input directory does not exist.", "input");
}
if (string.IsNullOrEmpty(Output))
{
throw new OptionException("output not specified.", "output");
}
string output;
try
{
output = Path.GetFullPath(Output);
}
catch (ArgumentException)
{
throw new OptionException("output is not a valid directory.", "output");
}
var groupingValue = GroupingOptionType.None;
if (string.Equals(Grouping, "NONE"))
{
groupingValue = GroupingOptionType.None;
}
else if (string.Equals(Grouping, "REGION"))
{
groupingValue = GroupingOptionType.Region;
}
else if (string.Equals(Grouping, "LETTER"))
{
groupingValue = GroupingOptionType.Letter;
}
else if (string.Equals(Grouping, "REGIONLETTER"))
{
groupingValue = GroupingOptionType.RegionLetter;
}
else if (string.Equals(Grouping, "LETTERREGION"))
{
groupingValue = GroupingOptionType.LetterRegion;
}
else
{
throw new OptionException("grouping is not valid.", "grouping");
}
var compressValue = CompressOptionType.None;
if (Compress)
{
compressValue = CompressOptionType.CCI;
}
var scrubValue = ScrubOptionType.None;
if (TrimScrub)
{
scrubValue = ScrubOptionType.TrimScrub;
}
else if (Scrub)
{
scrubValue = ScrubOptionType.Scrub;
}
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");
}
}
if (!Directory.Exists(output))
{
Directory.CreateDirectory(output);
}
string log;
FileStream? logStream = null;
if (!string.IsNullOrEmpty(Log))
{
try
{
log = Path.GetFullPath(Log);
string? dir = Path.GetDirectoryName(log);
if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
logStream = File.OpenWrite(log);
}
catch (ArgumentException)
{
throw new OptionException("log is not a valid filepath.", "log");
}
}
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);
logStream?.Write(Encoding.UTF8.GetBytes(message));
});
var config = new Config
{
InputPath = Input,
OutputPath = Output,
UnpackPath = Unpack,
GroupingOption = groupingValue,
RecurseInput = Recurse,
Uppercase = Uppercase,
CompressOption = compressValue,
NoSplit = NoSplit,
ScrubOption = scrubValue,
};
var gameData = GameDataHelper.LoadGameData();
var prevMessage = string.Empty;
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;
}
}
});
var repacker = new Repacker();
repacker.StartRepacking(gameData, config, progress, logger, new Stopwatch(), default);
logStream?.Dispose();
System.Console.WriteLine();
System.Console.WriteLine("Repack completed.");
}
catch (OptionException e)
{
ConsoleUtil.ShowOptionException(e, Action, version);
}
ConsoleUtil.ProcessWait(Wait);
}
}
}