mirror of
https://github.com/Team-Resurgent/Repackinator.git
synced 2026-08-15 02:18:07 -07:00
289 lines
11 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
|