diff --git a/IPA/Arguments.cs b/IPA/Arguments.cs new file mode 100644 index 00000000..f00110f9 --- /dev/null +++ b/IPA/Arguments.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IPA +{ + public class Arguments + { + public static Arguments Process = new Arguments(Environment.GetCommandLineArgs()); + + private List positional = new List(); + private Dictionary longFlags = new Dictionary(); + private Dictionary flags = new Dictionary(); + + private Arguments(string[] args) + { + foreach(var arg in args) + { + if (arg.StartsWith("--")) + { // parse as a long flag + var name = arg.Substring(2); // cut off first two chars + string value = null; + + if (name.Contains('=')) + { + var spl = name.Split('='); + name = spl[0]; + value = string.Join("=", spl, 1, spl.Length-1); + } + + longFlags.Add(name, value); + } + else if (arg.StartsWith("-")) + { // parse as flags + var argument = arg.Substring(1); // cut off first char + + StringBuilder subBuildState = new StringBuilder(); + bool parsingValue = false; + char mainChar = ' '; + foreach (char chr in argument) + { + if (!parsingValue) + { + if (chr == '=') + { + parsingValue = true; + } + else + { + mainChar = chr; + flags.Add(chr, null); + } + } + else + { + if (chr == ',') + { + parsingValue = false; + flags[mainChar] = subBuildState.ToString(); + subBuildState = new StringBuilder(); + } + else + { + subBuildState.Append(chr); + } + } + } + } + else + { // parse as positional + positional.Add(arg); + } + } + } + + public bool HasLongFlag(string flag) + { + return longFlags.ContainsKey(flag); + } + + public bool HasFlag(char flag) + { + return flags.ContainsKey(flag); + } + + public string GetLongFlagValue(string flag) + { + return longFlags[flag]; + } + + public string GetFlagValue(char flag) + { + return flags[flag]; + } + + public IReadOnlyList PositionalArgs => positional; + } +} diff --git a/IPA/IPA.csproj b/IPA/IPA.csproj index f782a57d..953e54dc 100644 --- a/IPA/IPA.csproj +++ b/IPA/IPA.csproj @@ -64,6 +64,7 @@ + diff --git a/IPA/PatchContext.cs b/IPA/PatchContext.cs index 8a2ab808..d720e3c8 100644 --- a/IPA/PatchContext.cs +++ b/IPA/PatchContext.cs @@ -22,7 +22,6 @@ namespace IPA public string EngineFile { get; private set; } public string EngineWebRequestFile { get; private set; } public string AssemblyFile { get; private set; } - public string[] Args { get; private set; } public string ProjectRoot { get; private set; } public string IPARoot { get; private set; } public string ShortcutPath { get; private set; } @@ -31,11 +30,10 @@ namespace IPA private PatchContext() { } - public static PatchContext Create(String[] args, string exe) + public static PatchContext Create(string exe) { var context = new PatchContext { - Args = args, Executable = exe }; context.ProjectRoot = new FileInfo(context.Executable).Directory.FullName; diff --git a/IPA/Program.cs b/IPA/Program.cs index ea246646..5233f6ae 100644 --- a/IPA/Program.cs +++ b/IPA/Program.cs @@ -22,15 +22,12 @@ namespace IPA { static void Main(string[] args) { - var ArgList = args.ToList(); - try { string arg = args.FirstOrDefault(s => s.StartsWith("--waitfor=")); - if (arg != null) + if (Arguments.Process.HasLongFlag("waitfor") && Arguments.Process.GetLongFlagValue("waitfor") != null) { - ArgList.Remove(arg); - int pid = int.Parse(arg.Split('=').Last()); + int pid = int.Parse(Arguments.Process.GetLongFlagValue("waitfor")); try { // wait for beat saber to exit (ensures we can modify the file) @@ -45,22 +42,21 @@ namespace IPA { PatchContext context; - var argExeName = ArgList.FirstOrDefault(s => s.EndsWith(".exe")); + var argExeName = Arguments.Process.PositionalArgs.FirstOrDefault(s => s.EndsWith(".exe")); if (argExeName == null) { //Fail("Drag an (executable) file on the exe!"); - context = PatchContext.Create(ArgList.ToArray(), - new DirectoryInfo(Directory.GetCurrentDirectory()).GetFiles() + context = PatchContext.Create(new DirectoryInfo(Directory.GetCurrentDirectory()).GetFiles() .First(o => o.FullName.EndsWith(".exe")) .FullName); } else { - context = PatchContext.Create(ArgList.ToArray(), argExeName); + context = PatchContext.Create(argExeName); } - bool isRevert = ArgList.Contains("--revert") || Keyboard.IsKeyDown(Keys.LMenu); + bool isRevert = Arguments.Process.HasLongFlag("revert") || Keyboard.IsKeyDown(Keys.LMenu); // Sanitizing Validate(context); @@ -112,8 +108,8 @@ namespace IPA { var nativePluginFolder = Path.Combine(context.DataPathDst, "Plugins"); bool isFlat = Directory.Exists(nativePluginFolder) && Directory.GetFiles(nativePluginFolder).Any(f => f.EndsWith(".dll")); - bool force = !BackupManager.HasBackup(context) || context.Args.Contains("-f") || - context.Args.Contains("--force"); + bool force = !BackupManager.HasBackup(context) || Arguments.Process.HasFlag('f') || + Arguments.Process.HasLongFlag("force"); var architecture = DetectArchitecture(context.Executable); Console.WriteLine("Architecture: {0}", architecture); @@ -203,7 +199,7 @@ namespace IPA { } - if (!Environment.CommandLine.Contains("--nowait")) + if (!Arguments.Process.HasLongFlag("nowait")) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Finished!"); @@ -233,7 +229,7 @@ namespace IPA { Console.WriteLine(""); Console.WriteLine("--- Done reverting ---"); - if (!Environment.CommandLine.Contains("--nowait") && !isNewVersion) { + if (!Arguments.Process.HasLongFlag("nowait") && !isNewVersion) { Console.WriteLine("\n\n[Press any key to quit]"); Console.ReadKey(); } @@ -242,22 +238,17 @@ namespace IPA { } private static void StartIfNeedBe(PatchContext context) { - string startArg = context.Args.FirstOrDefault(s => s.StartsWith("--start=")); - if (startArg != null) + if (Arguments.Process.HasLongFlag("start") && Arguments.Process.GetLongFlagValue("start") != null) { - var cmdlineSplit = startArg.Split('=').ToList(); - cmdlineSplit.RemoveAt(0); // remove first - var cmdline = string.Join("=", cmdlineSplit); - Process.Start(context.Executable, cmdline); + Process.Start(context.Executable, Arguments.Process.GetLongFlagValue("start")); } else { - var argList = context.Args.ToList(); - bool launch = argList.Remove("--launch"); + var argList = Arguments.Process.PositionalArgs.ToList(); argList.Remove(context.Executable); - if (launch) + if (Arguments.Process.HasLongFlag("launch")) { Process.Start(context.Executable, Args(argList.ToArray())); } @@ -338,7 +329,7 @@ namespace IPA { static void Fail(string message) { Console.Error.Write("ERROR: " + message); - if (!Environment.CommandLine.Contains("--nowait")) { + if (!Arguments.Process.HasLongFlag("nowait")) { Console.WriteLine("\n\n[Press any key to quit]"); Console.ReadKey(); } diff --git a/IPA/Properties/AssemblyInfo.cs b/IPA/Properties/AssemblyInfo.cs index 85e4516e..26f940c5 100644 --- a/IPA/Properties/AssemblyInfo.cs +++ b/IPA/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("3.8.2")] -[assembly: AssemblyFileVersion("3.8.2")] +[assembly: AssemblyVersion("3.8.3")] +[assembly: AssemblyFileVersion("3.8.3")] diff --git a/IPA/obj/Debug/IPA.csproj.CoreCompileInputs.cache b/IPA/obj/Debug/IPA.csproj.CoreCompileInputs.cache index d5116832..d0c0594d 100644 --- a/IPA/obj/Debug/IPA.csproj.CoreCompileInputs.cache +++ b/IPA/obj/Debug/IPA.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -33cd6c2ad2a5a7958d22e4f89028cf896273055b +854dcf24535098612cfeca06e87fe2b163332578 diff --git a/IllusionInjector/Updating/SelfPlugin.cs b/IllusionInjector/Updating/SelfPlugin.cs index 6b6b1b28..7d08f614 100644 --- a/IllusionInjector/Updating/SelfPlugin.cs +++ b/IllusionInjector/Updating/SelfPlugin.cs @@ -12,7 +12,7 @@ namespace IllusionInjector.Updating internal class SelfPlugin : IBeatSaberPlugin { internal const string IPA_Name = "Beat Saber IPA"; - internal const string IPA_Version = "3.8.2"; + internal const string IPA_Version = "3.8.3"; public string Name => IPA_Name;